Add complete user invitation system to enable multi-user tenants.
Changes:
- Created Invitation domain entity with 7-day expiration
- Implemented InviteUserCommand with security validation
- Implemented AcceptInvitationCommand (creates user + assigns role)
- Implemented GetPendingInvitationsQuery
- Implemented CancelInvitationCommand
- Added TenantInvitationsController with tenant-scoped endpoints
- Added public invitation acceptance endpoint to AuthController
- Created database migration for invitations table
- Registered InvitationRepository in DI container
- Created domain event handlers for audit trail
Security Features:
- Cannot invite as TenantOwner or AIAgent roles
- Cross-tenant validation on all endpoints
- Secure token generation and hashing
- RequireTenantAdmin policy for invite/list
- RequireTenantOwner policy for cancel
This UNBLOCKS 3 skipped Day 6 tests (RemoveUserFromTenant).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add complete email verification system with token-based verification.
Changes:
- Created EmailVerificationToken domain entity with expiration and verification tracking
- Created EmailVerifiedEvent domain event for audit trail
- Updated User entity with IsEmailVerified property and VerifyEmail method
- Created IEmailVerificationTokenRepository interface and implementation
- Created SecurityTokenService for secure token generation and SHA-256 hashing
- Created EmailVerificationTokenConfiguration for EF Core mapping
- Updated IdentityDbContext to include EmailVerificationTokens DbSet
- Created SendVerificationEmailCommand and handler for sending verification emails
- Created VerifyEmailCommand and handler for email verification
- Added POST /api/auth/verify-email endpoint to AuthController
- Integrated email verification into RegisterTenantCommandHandler
- Registered all new services in DependencyInjection
- Created and applied AddEmailVerification database migration
- Build successful with no compilation errors
Database Schema:
- email_verification_tokens table with indexes on token_hash and user_id
- 24-hour token expiration
- One-time use tokens with verification tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add complete email service infrastructure with Mock and SMTP implementations.
Changes:
- Created EmailMessage domain model for email data
- Added IEmailService interface for email sending
- Implemented MockEmailService for development/testing (logs emails)
- Implemented SmtpEmailService for production SMTP sending
- Added IEmailTemplateService interface for email templates
- Implemented EmailTemplateService with HTML templates for verification, password reset, and invitation emails
- Registered email services in DependencyInjection with provider selection
- Added email configuration to appsettings.Development.json (Mock provider by default)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented domain event raising in command handlers to enable audit logging and event-driven architecture for key Identity module operations.
Changes:
- Updated LoginCommand to include IpAddress and UserAgent fields for audit trail
- Updated AuthController to extract and pass IP address and user agent from HTTP context
- Modified LoginCommandHandler to raise UserLoggedInEvent on successful login
- Updated AssignUserRoleCommand to include AssignedBy field for audit purposes
- Modified AssignUserRoleCommandHandler to raise UserRoleAssignedEvent with previous role tracking
- Updated RemoveUserFromTenantCommand to include RemovedBy and Reason fields
- Modified RemoveUserFromTenantCommandHandler to raise UserRemovedFromTenantEvent before deletion
- Added domain methods to User aggregate: RecordLoginWithEvent, RaiseRoleAssignedEvent, RaiseRemovedFromTenantEvent
- Updated TenantUsersController to extract current user ID from JWT claims and pass to commands
Technical Details:
- All event raising follows aggregate root encapsulation pattern
- Domain events are persisted through repository UpdateAsync calls
- Event handlers will automatically log these events for audit trail
- Maintains backward compatibility with existing login flow
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add complete domain events dispatching infrastructure and critical event handlers for Identity module.
Changes:
- Added IMediator injection to IdentityDbContext
- Implemented SaveChangesAsync override to dispatch domain events before persisting
- Made DomainEvent base class implement INotification (added MediatR.Contracts dependency)
- Created 3 new domain events: UserRoleAssignedEvent, UserRemovedFromTenantEvent, UserLoggedInEvent
- Implemented 4 event handlers with structured logging:
- UserRoleAssignedEventHandler (audit log, cache invalidation placeholder)
- UserRemovedFromTenantEventHandler (notification placeholder)
- UserLoggedInEventHandler (login tracking placeholder)
- TenantCreatedEventHandler (welcome email placeholder)
- Updated unit tests to inject mock IMediator into IdentityDbContext
Technical Details:
- Domain events are now published via MediatR within the same transaction
- Events are dispatched BEFORE SaveChangesAsync to ensure atomicity
- Event handlers auto-registered by MediatR assembly scanning
- All handlers include structured logging for observability
Next Steps (Phase 3):
- Update command handlers to raise new events (UserLoggedInEvent, UserRoleAssignedEvent)
- Add event raising logic to User/Tenant aggregates
- Implement audit logging persistence (currently just logging)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add complete role management functionality for tenant administrators to manage user roles within their tenants.
Changes:
- Extended IUserTenantRoleRepository with pagination, role counting, and last owner check methods
- Extended IUserRepository with GetByIdAsync(Guid) and GetByIdsAsync for flexible user retrieval
- Extended IRefreshTokenRepository with GetByUserAndTenantAsync and UpdateRangeAsync
- Implemented repository methods in Infrastructure layer
- Created DTOs: UserWithRoleDto and PagedResultDto<T>
- Implemented ListTenantUsersQuery with pagination support
- Implemented AssignUserRoleCommand to assign/update user roles
- Implemented RemoveUserFromTenantCommand with token revocation
- Created TenantUsersController with 4 endpoints (list, assign, remove, get-roles)
- Added comprehensive PowerShell test script
Security Features:
- Only TenantOwner can assign/update/remove roles
- Prevents removal of last TenantOwner (lockout protection)
- Prevents manual assignment of AIAgent role (reserved for MCP)
- Cross-tenant access protection
- Automatic refresh token revocation when user removed
API Endpoints:
- GET /api/tenants/{id}/users - List users with roles (paginated)
- POST /api/tenants/{id}/users/{userId}/role - Assign/update role
- DELETE /api/tenants/{id}/users/{userId} - Remove user from tenant
- GET /api/tenants/roles - Get available roles
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented Role-Based Access Control (RBAC) with 5 tenant-level roles following Clean Architecture principles.
Changes:
- Created TenantRole enum (TenantOwner, TenantAdmin, TenantMember, TenantGuest, AIAgent)
- Created UserTenantRole entity with repository pattern
- Updated JWT service to include role claims (tenant_role, role)
- Updated RegisterTenant to auto-assign TenantOwner role
- Updated Login to query and include user role in JWT
- Updated RefreshToken to preserve role claims
- Added authorization policies in Program.cs (RequireTenantOwner, RequireTenantAdmin, etc.)
- Updated /api/auth/me endpoint to return role information
- Created EF Core migration for user_tenant_roles table
- Applied database migration successfully
Database:
- New table: identity.user_tenant_roles
- Columns: id, user_id, tenant_id, role, assigned_at, assigned_by_user_id
- Indexes: user_id, tenant_id, role, unique(user_id, tenant_id)
- Foreign keys: CASCADE on user and tenant deletion
Testing:
- Created test-rbac.ps1 PowerShell script
- All RBAC tests passing
- JWT tokens contain role claims
- Role persists across login and token refresh
Documentation:
- DAY5-PHASE2-RBAC-IMPLEMENTATION-SUMMARY.md with complete implementation details
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>