TaskAssignment Model Documentation
Overview​
The TaskAssignment model tracks the assignment and completion of tasks by team members in CODITECT. It provides detailed tracking of who is working on what, time logging, and work history. This model bridges the Task and Member models, enabling work allocation, progress tracking, and time management across projects.
Model Structure​
Core Fields​
| Field | Type | Description | Constraints |
|---|---|---|---|
assignment_id | UUID | Unique assignment identifier | Primary key, auto-generated |
tenant_id | UUID | Associated tenant | Foreign key to Tenant |
task_id | UUID | Assigned task | Foreign key to Task |
member_id | UUID | Assigned member | Foreign key to Member |
assigned_at | DateTime | Assignment timestamp | Auto-set to current time |
assigned_by | UUID | Who made the assignment | Foreign key to User |
completed_at | DateTime | Completion timestamp | Set when task completed |
hours_logged | f32 | Total hours worked | Accumulates over time |
notes | String (Optional) | Work notes and time log | Append-only log format |
Example Records​
Active Assignment​
{
"assignment_id": "550e8400-e29b-41d4-a716-446655440000",
"tenant_id": "123e4567-e89b-12d3-a456-426614174000",
"task_id": "456e7890-e89b-12d3-a456-426614174000",
"member_id": "789e0123-e89b-12d3-a456-426614174000",
"assigned_at": "2025-08-28T09:00:00Z",
"assigned_by": "890e1234-e89b-12d3-a456-426614174000",
"completed_at": null,
"hours_logged": 4.5,
"notes": "[2025-08-28 10:30] +2.5h: Initial implementation\n[2025-08-28 15:45] +2.0h: Added unit tests"
}
Completed Assignment​
{
"assignment_id": "660e8400-e29b-41d4-a716-446655440000",
"tenant_id": "123e4567-e89b-12d3-a456-426614174000",
"task_id": "567e8901-e89b-12d3-a456-426614174000",
"member_id": "901e2345-e89b-12d3-a456-426614174000",
"assigned_at": "2025-08-25T14:00:00Z",
"assigned_by": "890e1234-e89b-12d3-a456-426614174000",
"completed_at": "2025-08-27T17:30:00Z",
"hours_logged": 12.0,
"notes": "[2025-08-25 14:30] +3.0h: Research and planning\n[2025-08-26 09:00] +5.0h: Core implementation\n[2025-08-27 13:00] +4.0h: Testing and documentation"
}
AI Agent Assignment​
{
"assignment_id": "770e8400-e29b-41d4-a716-446655440000",
"tenant_id": "123e4567-e89b-12d3-a456-426614174000",
"task_id": "678e9012-e89b-12d3-a456-426614174000",
"member_id": "ai-agent-test-writer-001",
"assigned_at": "2025-08-29T10:15:00Z",
"assigned_by": "890e1234-e89b-12d3-a456-426614174000",
"completed_at": "2025-08-29T10:45:00Z",
"hours_logged": 0.5,
"notes": "[2025-08-29 10:45] +0.5h: Generated 15 unit tests with 98% coverage"
}
Time Tracking​
Hour Logging Format​
The notes field maintains an append-only log of time entries:
[YYYY-MM-DD HH:MM] +X.XXh: Description of work done
Example progression:
Initial: null
After first log: "[2025-08-29 09:00] +2.0h: Setup development environment"
After second log: "[2025-08-29 09:00] +2.0h: Setup development environment\n[2025-08-29 14:00] +3.5h: Implemented authentication"
Time Calculation Methods​
impl TaskAssignment {
// Add hours with optional notes
pub fn log_hours(&mut self, hours: f32, notes: Option<String>) {
self.hours_logged += hours;
// Append timestamped entry to notes
}
// Calculate assignment duration
pub fn duration(&self) -> Option<Duration> {
self.completed_at
.map(|completed| completed - self.assigned_at)
}
// Get average hours per day
pub fn daily_average(&self) -> f32 {
let days = self.duration()
.map(|d| d.num_days() as f32)
.unwrap_or(1.0)
.max(1.0);
self.hours_logged / days
}
}
Database Schema​
Primary Storage Pattern​
Key: /{tenant_id}/task_assignments/{assignment_id}
Value: JSON serialized TaskAssignment object
Secondary Indexes​
# Assignments by task
/{tenant_id}/assignments_by_task/{task_id} -> [assignment_ids]
# Assignments by member
/{tenant_id}/assignments_by_member/{member_id} -> [assignment_ids]
# Active assignments
/{tenant_id}/active_assignments/{member_id} -> [assignment_ids]
# Completed assignments by date
/{tenant_id}/completed_assignments/{YYYY-MM-DD} -> [assignment_ids]
# Hours logged by member and date
/{tenant_id}/hours_by_member/{member_id}/{YYYY-MM-DD} -> total_hours
Related Code​
Source Files​
- Model:
/src/models/task_assignment.rs - Repository:
/src/db/repositories/task_assignment_repository.rs - Service:
/src/services/assignment_service.rs - Time Tracking:
/src/services/time_tracking_service.rs - Tests:
/src/models/tests/task_assignment_tests.rs
Key Methods​
impl TaskAssignment {
fn new(tenant_id: Uuid, task_id: Uuid, member_id: Uuid, assigned_by: Uuid) -> Self
fn complete(&mut self)
fn log_hours(&mut self, hours: f32, notes: Option<String>)
fn is_completed(&self) -> bool
fn duration(&self) -> Option<Duration>
}
impl TaskAssignmentRepository {
async fn create(&self, assignment: &TaskAssignment) -> Result<()>
async fn get_by_id(&self, tenant_id: &Uuid, assignment_id: &Uuid) -> Result<Option<TaskAssignment>>
async fn get_by_task(&self, tenant_id: &Uuid, task_id: &Uuid) -> Result<Vec<TaskAssignment>>
async fn get_by_member(&self, tenant_id: &Uuid, member_id: &Uuid) -> Result<Vec<TaskAssignment>>
async fn get_active_assignments(&self, tenant_id: &Uuid, member_id: &Uuid) -> Result<Vec<TaskAssignment>>
}
API Endpoints​
Assignment Management​
- POST
/api/tasks/{task_id}/assign- Assign task to member - PUT
/api/assignments/{assignment_id}/complete- Mark as complete - DELETE
/api/assignments/{assignment_id}- Unassign task
Time Tracking​
- POST
/api/assignments/{assignment_id}/log-time- Log hours worked - GET
/api/assignments/{assignment_id}/time-entries- Get time log - GET
/api/members/{member_id}/timesheet- Member timesheet
Queries​
- GET
/api/tasks/{task_id}/assignments- Task assignment history - GET
/api/members/{member_id}/assignments- Member's assignments - GET
/api/assignments/active- All active assignments
Business Rules​
Assignment Rules​
- Single Active: One member per task at a time
- Project Member: Assignee must be project member
- Availability Check: Member must have capacity
- Permission Required: Assigner needs AssignTask permission
- No Self-Assignment: Members cannot self-assign (unless permitted)
Time Logging Rules​
- Incremental Only: Cannot reduce logged hours
- Active Only: Can only log time on active assignments
- Reasonable Limits: Daily hour limit (e.g., 24 hours)
- Notes Required: Time entries should have descriptions
- Audit Trail: All changes tracked
Completion Rules​
- One-Way: Cannot un-complete assignments
- Final Hours: Log remaining hours before completion
- Task Update: Completing assignment updates task status
- Notification: Notify task creator and PM
- Auto-Archive: Move to historical storage
Use Cases​
Standard Task Assignment​
// Manager assigns task to developer
let assignment = TaskAssignment::new(
tenant_id,
task_id,
developer_id,
manager_id
);
// Check member availability
if !member_service.can_take_task(developer_id).await? {
return Err("Member at capacity");
}
assignment_repo.create(&assignment).await?;
notification_service.notify_assignment(developer_id, task_id).await?;
Time Tracking Workflow​
// Developer logs daily work
let mut assignment = assignment_repo
.get_active_for_member_and_task(member_id, task_id)
.await?;
assignment.log_hours(
3.5,
Some("Implemented user authentication endpoint".to_string())
);
assignment_repo.update(&assignment).await?;
// Auto-update task progress
task_service.update_progress_from_hours(task_id, assignment.hours_logged).await?;
AI Agent Assignment​
// Assign code review to AI agent
let agent_member = member_repo
.find_available_agent("code_reviewer")
.await?;
let assignment = TaskAssignment::new(
tenant_id,
review_task_id,
agent_member.member_id,
system_user_id
);
// Trigger agent execution
agent_service.execute_task(agent_member.member_id, review_task_id).await?;
Integration Patterns​
With Task Model​
// Update task when assignment changes
impl TaskService {
async fn on_assignment_created(&self, assignment: &TaskAssignment) {
let mut task = self.get_task(assignment.task_id).await?;
task.assignee_id = Some(assignment.member_id);
task.status = TaskStatus::InProgress;
self.update_task(task).await?;
}
async fn on_assignment_completed(&self, assignment: &TaskAssignment) {
let mut task = self.get_task(assignment.task_id).await?;
task.actual_hours = Some(assignment.hours_logged);
task.status = TaskStatus::UnderReview;
self.update_task(task).await?;
}
}
With Member Model​
// Update member capacity
impl MemberService {
async fn on_assignment_created(&self, assignment: &TaskAssignment) {
let mut member = self.get_member(assignment.member_id).await?;
member.capacity.current_task_count += 1;
self.update_member(member).await?;
}
async fn on_assignment_completed(&self, assignment: &TaskAssignment) {
let mut member = self.get_member(assignment.member_id).await?;
member.capacity.current_task_count -= 1;
self.update_member(member).await?;
}
}
Reporting & Analytics​
Time Reports​
struct TimeReport {
member_id: Uuid,
period: DateRange,
total_hours: f32,
completed_tasks: u32,
average_task_duration: Duration,
daily_breakdown: HashMap<Date, f32>
}
Assignment Metrics​
- Velocity: Tasks completed per sprint
- Cycle Time: Assignment to completion duration
- Utilization: Logged hours vs available hours
- Accuracy: Estimated vs actual hours
- Distribution: Work spread across team
Sample Queries​
// Get team's weekly hours
let weekly_hours = assignment_repo
.get_hours_for_team_in_period(
project_id,
start_of_week,
end_of_week
)
.await?;
// Find overdue assignments
let overdue = assignment_repo
.get_active_assignments_older_than(Duration::days(14))
.await?;
// Calculate member efficiency
let efficiency = completed_hours / estimated_hours;
Performance Optimization​
Indexing Strategy​
- Primary key on assignment_id
- Composite index on (member_id, completed_at)
- Index on (task_id, assigned_at)
- Partial index on active assignments
Caching​
struct AssignmentCache {
// Active assignments per member
active_by_member: HashMap<Uuid, Vec<AssignmentSummary>>,
// Recent completions
recent_completions: LruCache<Uuid, TaskAssignment>,
// Hours logged today
today_hours: HashMap<Uuid, f32>
}
Archival Strategy​
- Archive completed assignments after 90 days
- Aggregate historical data monthly
- Keep summary statistics indefinitely
- Compress time log entries
Security & Privacy​
Access Control​
- Members see own assignments
- Managers see team assignments
- Time logs visible to authorized users
- Sensitive notes can be redacted
Audit Requirements​
- Log all assignment changes
- Track who assigns/unassigns
- Record time entry modifications
- Monitor unusual patterns
Best Practices​
Assignment Management​
- Clear task descriptions before assignment
- Set realistic time estimates
- Regular check-ins on long tasks
- Reassign stalled tasks promptly
- Document reassignment reasons
Time Tracking​
- Log time daily for accuracy
- Include meaningful descriptions
- Break down large time blocks
- Review logs before completion
- Validate against estimates
Future Enhancements​
Advanced Features​
- Smart Assignment: AI-based member matching
- Predictive Duration: ML-based time estimates
- Workload Balancing: Automatic distribution
- Time Approval: Manager review workflow
Integration Features​
- Calendar Sync: Block time for assignments
- IDE Integration: Automatic time tracking
- Git Integration: Link commits to time
- Slack Updates: Real-time notifications
Analytics Enhancements​
- Burnout Detection: Overwork alerts
- Skill Tracking: Task type analysis
- Team Insights: Collaboration patterns
- Cost Analysis: Hour-based project costs
Last Updated: 2025-08-29 Version: 1.0