diff --git a/DocumentOperator.Application/AddStamp/AddStampCommand.cs b/DocumentOperator.Application/AddStamp/AddStampCommand.cs
new file mode 100644
index 0000000..9352298
--- /dev/null
+++ b/DocumentOperator.Application/AddStamp/AddStampCommand.cs
@@ -0,0 +1,125 @@
+using FluentValidation;
+using MediatR;
+
+namespace DocumentOperator.Application.AddStamp;
+
+///
+/// Command to add a stamp (text, image, or predefined) to PDF pages.
+/// Combines Command, Handler, and Validator in a single file (Vertical Slice pattern).
+///
+public record AddStampCommand : IRequest
+{
+ public required Stream PdfStream { get; init; }
+ public required Domain.Models.ValueObjects.StampType StampType { get; init; }
+ public int[]? PageNumbers { get; init; } // null = all pages
+ public required (double X, double Y) Position { get; init; }
+ public (double Width, double Height)? Size { get; init; }
+ public Domain.Models.ValueObjects.AnnotationOrigin Origin { get; init; } = Domain.Models.ValueObjects.AnnotationOrigin.BottomLeft;
+ public string? Text { get; init; }
+ public string? FontName { get; init; }
+ public double? FontSize { get; init; }
+ public string? Color { get; init; }
+ public double? Opacity { get; init; }
+ public double? Rotation { get; init; }
+ public Domain.Models.ValueObjects.StampPlacement Placement { get; init; } = Domain.Models.ValueObjects.StampPlacement.Foreground;
+ public byte[]? ImageBytes { get; init; }
+ public Domain.Models.ValueObjects.PredefinedStampType? PredefinedType { get; init; }
+}
+
+///
+/// Handler for AddStampCommand.
+///
+public class AddStampHandler(Common.Interfaces.IPdfProcessor pdfProcessor) : IRequestHandler
+{
+ public async Task Handle(AddStampCommand command, CancellationToken cancellationToken)
+ {
+ return await pdfProcessor.AddStampAsync(
+ command.PdfStream,
+ command.StampType,
+ command.PageNumbers,
+ command.Position,
+ command.Size,
+ command.Origin,
+ command.Text,
+ command.FontName,
+ command.FontSize,
+ command.Color,
+ command.Opacity,
+ command.Rotation,
+ command.Placement,
+ command.ImageBytes,
+ command.PredefinedType
+ );
+ }
+}
+
+///
+/// Validator for AddStampCommand.
+///
+public class AddStampValidator : AbstractValidator
+{
+ public AddStampValidator()
+ {
+ RuleFor(x => x.PdfStream)
+ .NotNull().WithMessage("PDF stream is required");
+
+ RuleFor(x => x.Position.X)
+ .GreaterThanOrEqualTo(0).WithMessage("Position X must be >= 0");
+
+ RuleFor(x => x.Position.Y)
+ .GreaterThanOrEqualTo(0).WithMessage("Position Y must be >= 0");
+
+ // Text stamp validation
+ When(x => x.StampType == Domain.Models.ValueObjects.StampType.Text, () =>
+ {
+ RuleFor(x => x.Text)
+ .NotEmpty().WithMessage("Text is required for Text stamp type");
+ });
+
+ // Image stamp validation
+ When(x => x.StampType == Domain.Models.ValueObjects.StampType.Image, () =>
+ {
+ RuleFor(x => x.ImageBytes)
+ .NotNull().WithMessage("Image bytes are required for Image stamp type")
+ .Must(bytes => bytes != null && bytes.Length > 0).WithMessage("Image bytes cannot be empty");
+ });
+
+ // Predefined stamp validation
+ When(x => x.StampType == Domain.Models.ValueObjects.StampType.Predefined, () =>
+ {
+ RuleFor(x => x.PredefinedType)
+ .NotNull().WithMessage("Predefined type is required for Predefined stamp type");
+ });
+
+ // Optional parameter validations
+ When(x => x.Opacity.HasValue, () =>
+ {
+ RuleFor(x => x.Opacity!.Value)
+ .InclusiveBetween(0.0, 1.0).WithMessage("Opacity must be between 0.0 and 1.0");
+ });
+
+ When(x => x.Rotation.HasValue, () =>
+ {
+ RuleFor(x => x.Rotation!.Value)
+ .InclusiveBetween(0.0, 360.0).WithMessage("Rotation must be between 0 and 360 degrees");
+ });
+
+ When(x => x.FontSize.HasValue, () =>
+ {
+ RuleFor(x => x.FontSize!.Value)
+ .GreaterThan(0).WithMessage("Font size must be positive");
+ });
+
+ When(x => !string.IsNullOrWhiteSpace(x.Color), () =>
+ {
+ RuleFor(x => x.Color!)
+ .Matches(@"^[0-9A-Fa-f]{6}$").WithMessage("Color must be 6-digit hex (e.g., 'FF0000')");
+ });
+
+ When(x => x.PageNumbers != null, () =>
+ {
+ RuleFor(x => x.PageNumbers!)
+ .Must(pages => pages.All(p => p > 0)).WithMessage("All page numbers must be >= 1");
+ });
+ }
+}