diff --git a/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Aggregates/ProjectAggregate/Sprint.cs b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Aggregates/ProjectAggregate/Sprint.cs
new file mode 100644
index 0000000..e4b5705
--- /dev/null
+++ b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Aggregates/ProjectAggregate/Sprint.cs
@@ -0,0 +1,165 @@
+using ColaFlow.Shared.Kernel.Common;
+using ColaFlow.Modules.ProjectManagement.Domain.Exceptions;
+using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
+using ColaFlow.Modules.ProjectManagement.Domain.Enums;
+using ColaFlow.Modules.ProjectManagement.Domain.Events;
+
+namespace ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate;
+
+///
+/// Sprint Entity (part of Project aggregate)
+///
+public class Sprint : Entity
+{
+ public new SprintId Id { get; private set; }
+ public TenantId TenantId { get; private set; }
+ public ProjectId ProjectId { get; private set; }
+ public string Name { get; private set; }
+ public string? Goal { get; private set; }
+ public DateTime StartDate { get; private set; }
+ public DateTime EndDate { get; private set; }
+ public SprintStatus Status { get; private set; }
+
+ private readonly List _taskIds = new();
+ public IReadOnlyCollection TaskIds => _taskIds.AsReadOnly();
+
+ public DateTime CreatedAt { get; private set; }
+ public UserId CreatedBy { get; private set; }
+ public DateTime? UpdatedAt { get; private set; }
+
+ // EF Core constructor
+ private Sprint()
+ {
+ Id = null!;
+ TenantId = null!;
+ ProjectId = null!;
+ Name = null!;
+ Status = null!;
+ CreatedBy = null!;
+ }
+
+ ///
+ /// Create a new Sprint
+ ///
+ public static Sprint Create(
+ TenantId tenantId,
+ ProjectId projectId,
+ string name,
+ string? goal,
+ DateTime startDate,
+ DateTime endDate,
+ UserId createdBy)
+ {
+ ValidateName(name);
+ ValidateDates(startDate, endDate);
+
+ return new Sprint
+ {
+ Id = SprintId.Create(),
+ TenantId = tenantId,
+ ProjectId = projectId,
+ Name = name,
+ Goal = goal,
+ StartDate = startDate,
+ EndDate = endDate,
+ Status = SprintStatus.Planned,
+ CreatedAt = DateTime.UtcNow,
+ CreatedBy = createdBy
+ };
+ }
+
+ ///
+ /// Update sprint details
+ ///
+ public void UpdateDetails(string name, string? goal, DateTime startDate, DateTime endDate)
+ {
+ if (Status.Name == SprintStatus.Completed.Name)
+ throw new DomainException("Cannot update a completed sprint");
+
+ ValidateName(name);
+ ValidateDates(startDate, endDate);
+
+ Name = name;
+ Goal = goal;
+ StartDate = startDate;
+ EndDate = endDate;
+ UpdatedAt = DateTime.UtcNow;
+ }
+
+ ///
+ /// Start the sprint (Planned → Active)
+ ///
+ public void Start()
+ {
+ if (Status.Name != SprintStatus.Planned.Name)
+ throw new DomainException($"Cannot start sprint in {Status.Name} status. Sprint must be in Planned status.");
+
+ Status = SprintStatus.Active;
+ UpdatedAt = DateTime.UtcNow;
+ }
+
+ ///
+ /// Complete the sprint (Active → Completed)
+ ///
+ public void Complete()
+ {
+ if (Status.Name != SprintStatus.Active.Name)
+ throw new DomainException($"Cannot complete sprint in {Status.Name} status. Sprint must be in Active status.");
+
+ Status = SprintStatus.Completed;
+ UpdatedAt = DateTime.UtcNow;
+ }
+
+ ///
+ /// Add a task to the sprint
+ ///
+ public void AddTask(TaskId taskId)
+ {
+ if (Status.Name == SprintStatus.Completed.Name)
+ throw new DomainException("Cannot add tasks to a completed sprint");
+
+ if (_taskIds.Any(t => t.Value == taskId.Value))
+ throw new DomainException("Task is already in this sprint");
+
+ _taskIds.Add(taskId);
+ UpdatedAt = DateTime.UtcNow;
+ }
+
+ ///
+ /// Remove a task from the sprint
+ ///
+ public void RemoveTask(TaskId taskId)
+ {
+ if (Status.Name == SprintStatus.Completed.Name)
+ throw new DomainException("Cannot remove tasks from a completed sprint");
+
+ var task = _taskIds.FirstOrDefault(t => t.Value == taskId.Value);
+ if (task == null)
+ throw new DomainException("Task is not in this sprint");
+
+ _taskIds.Remove(task);
+ UpdatedAt = DateTime.UtcNow;
+ }
+
+ private static void ValidateName(string name)
+ {
+ if (string.IsNullOrWhiteSpace(name))
+ throw new DomainException("Sprint name cannot be empty");
+
+ if (name.Length > 200)
+ throw new DomainException("Sprint name cannot exceed 200 characters");
+ }
+
+ private static void ValidateDates(DateTime startDate, DateTime endDate)
+ {
+ if (endDate <= startDate)
+ throw new DomainException("Sprint end date must be after start date");
+
+ var duration = (endDate - startDate).Days;
+ if (duration > 30)
+ throw new DomainException("Sprint duration cannot exceed 30 days");
+
+ if (duration < 1)
+ throw new DomainException("Sprint duration must be at least 1 day");
+ }
+}
diff --git a/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Enums/SprintStatus.cs b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Enums/SprintStatus.cs
new file mode 100644
index 0000000..ca201a2
--- /dev/null
+++ b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Enums/SprintStatus.cs
@@ -0,0 +1,35 @@
+namespace ColaFlow.Modules.ProjectManagement.Domain.Enums;
+
+///
+/// Sprint Status
+///
+public class SprintStatus
+{
+ public string Name { get; init; }
+
+ public static readonly SprintStatus Planned = new() { Name = "Planned" };
+ public static readonly SprintStatus Active = new() { Name = "Active" };
+ public static readonly SprintStatus Completed = new() { Name = "Completed" };
+
+ private SprintStatus() { Name = string.Empty; }
+
+ public static SprintStatus FromString(string status)
+ {
+ return status?.ToLowerInvariant() switch
+ {
+ "planned" => Planned,
+ "active" => Active,
+ "completed" => Completed,
+ _ => throw new ArgumentException($"Invalid sprint status: {status}", nameof(status))
+ };
+ }
+
+ public static IEnumerable GetAll()
+ {
+ yield return Planned;
+ yield return Active;
+ yield return Completed;
+ }
+
+ public override string ToString() => Name;
+}
diff --git a/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintCompletedEvent.cs b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintCompletedEvent.cs
new file mode 100644
index 0000000..017f6c1
--- /dev/null
+++ b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintCompletedEvent.cs
@@ -0,0 +1,8 @@
+using MediatR;
+
+namespace ColaFlow.Modules.ProjectManagement.Domain.Events;
+
+///
+/// Event raised when a Sprint is completed
+///
+public sealed record SprintCompletedEvent(Guid SprintId, string SprintName, Guid ProjectId, int TaskCount) : INotification;
diff --git a/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintCreatedEvent.cs b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintCreatedEvent.cs
new file mode 100644
index 0000000..f2ba0e6
--- /dev/null
+++ b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintCreatedEvent.cs
@@ -0,0 +1,8 @@
+using MediatR;
+
+namespace ColaFlow.Modules.ProjectManagement.Domain.Events;
+
+///
+/// Event raised when a Sprint is created
+///
+public sealed record SprintCreatedEvent(Guid SprintId, string SprintName, Guid ProjectId) : INotification;
diff --git a/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintDeletedEvent.cs b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintDeletedEvent.cs
new file mode 100644
index 0000000..7ecb885
--- /dev/null
+++ b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintDeletedEvent.cs
@@ -0,0 +1,8 @@
+using MediatR;
+
+namespace ColaFlow.Modules.ProjectManagement.Domain.Events;
+
+///
+/// Event raised when a Sprint is deleted
+///
+public sealed record SprintDeletedEvent(Guid SprintId, string SprintName, Guid ProjectId) : INotification;
diff --git a/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintStartedEvent.cs b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintStartedEvent.cs
new file mode 100644
index 0000000..2839d82
--- /dev/null
+++ b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintStartedEvent.cs
@@ -0,0 +1,8 @@
+using MediatR;
+
+namespace ColaFlow.Modules.ProjectManagement.Domain.Events;
+
+///
+/// Event raised when a Sprint is started
+///
+public sealed record SprintStartedEvent(Guid SprintId, string SprintName, Guid ProjectId) : INotification;
diff --git a/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintUpdatedEvent.cs b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintUpdatedEvent.cs
new file mode 100644
index 0000000..36dcc4c
--- /dev/null
+++ b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/SprintUpdatedEvent.cs
@@ -0,0 +1,8 @@
+using MediatR;
+
+namespace ColaFlow.Modules.ProjectManagement.Domain.Events;
+
+///
+/// Event raised when a Sprint is updated
+///
+public sealed record SprintUpdatedEvent(Guid SprintId, string SprintName, Guid ProjectId) : INotification;
diff --git a/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/TaskAddedToSprintEvent.cs b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/TaskAddedToSprintEvent.cs
new file mode 100644
index 0000000..11aff2b
--- /dev/null
+++ b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/TaskAddedToSprintEvent.cs
@@ -0,0 +1,8 @@
+using MediatR;
+
+namespace ColaFlow.Modules.ProjectManagement.Domain.Events;
+
+///
+/// Event raised when a Task is added to a Sprint
+///
+public sealed record TaskAddedToSprintEvent(Guid SprintId, Guid TaskId, Guid ProjectId) : INotification;
diff --git a/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/TaskRemovedFromSprintEvent.cs b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/TaskRemovedFromSprintEvent.cs
new file mode 100644
index 0000000..eb9981f
--- /dev/null
+++ b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/Events/TaskRemovedFromSprintEvent.cs
@@ -0,0 +1,8 @@
+using MediatR;
+
+namespace ColaFlow.Modules.ProjectManagement.Domain.Events;
+
+///
+/// Event raised when a Task is removed from a Sprint
+///
+public sealed record TaskRemovedFromSprintEvent(Guid SprintId, Guid TaskId, Guid ProjectId) : INotification;
diff --git a/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/ValueObjects/SprintId.cs b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/ValueObjects/SprintId.cs
new file mode 100644
index 0000000..8eb3884
--- /dev/null
+++ b/colaflow-api/src/Modules/ProjectManagement/ColaFlow.Modules.ProjectManagement.Domain/ValueObjects/SprintId.cs
@@ -0,0 +1,25 @@
+namespace ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
+
+///
+/// Sprint ID Value Object
+///
+public sealed record SprintId
+{
+ public Guid Value { get; init; }
+
+ private SprintId(Guid value)
+ {
+ if (value == Guid.Empty)
+ throw new ArgumentException("SprintId cannot be empty", nameof(value));
+
+ Value = value;
+ }
+
+ public static SprintId Create() => new(Guid.NewGuid());
+
+ public static SprintId From(Guid value) => new(value);
+
+ public override string ToString() => Value.ToString();
+
+ public static implicit operator Guid(SprintId sprintId) => sprintId.Value;
+}