using Insight.Database; using PlanTempus.Core; using PlanTempus.Core.Entities.Users; using System.Data; namespace PlanTempus.Database.Core { public class UserService { public record UserCreateCommand(string CorrelationId, string Email, string Password); private readonly IDbConnection _db; public UserService(IDbConnection db) { _db = db; } public async Task CreateUser(UserCreateCommand command) { var user = new User { Email = command.Email, PasswordHash = new SecureTokenizer().TokenizeText(command.Password), SecurityStamp = Guid.NewGuid().ToString(), EmailConfirmed = false, CreatedDate = DateTime.UtcNow }; var userId = await _db.ExecuteScalarAsync(@$" INSERT INTO users (email, password_hash, security_stamp, email_confirmed, created_at) VALUES (@Email, @PasswordHash, @SecurityStamp, @EmailConfirmed, @CreatedDate) RETURNING id", user); } public async Task CreateOrganization(int userId, string organizationConnectionString) { var schema = "dev"; using var transaction = _db.OpenWithTransaction(); try { // Create organization var organization = new Organization { ConnectionString = organizationConnectionString, CreatedDate = DateTime.UtcNow, CreatedBy = userId, IsActive = true }; var organizationId = await _db.ExecuteScalarAsync(@$" INSERT INTO {schema}.organizations (connection_string, created_date, is_active) VALUES (@ConnectionString, @CreatedDate, @IsActive) RETURNING id", organization); // Link user to organization var userOrganization = new UserOrganization { UserId = userId, OrganizationId = organizationId, CreatedDate = DateTime.UtcNow }; await _db.ExecuteAsync(@$" INSERT INTO {schema}.user_organizations (user_id, organization_id, created_date) VALUES (@UserId, @OrganizationId, @CreatedDate)", userOrganization); transaction.Commit(); } catch { transaction.Rollback(); throw; } } } }