Initial commit: Open sourcing all of the Maple Open Technologies code.

This commit is contained in:
Bartlomiej Mika 2025-12-02 14:33:08 -05:00
commit 755d54a99d
2010 changed files with 448675 additions and 0 deletions

View file

@ -0,0 +1,115 @@
// codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/repo/user/create.go
package user
import (
"context"
"fmt"
"time"
"github.com/gocql/gocql"
"go.uber.org/zap"
dom_user "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/user"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/validation"
)
func (impl userStorerImpl) Create(ctx context.Context, user *dom_user.User) error {
// Ensure we have a valid UUID
if user.ID == (gocql.UUID{}) {
user.ID = gocql.TimeUUID()
}
// Set timestamps if not set
now := time.Now()
if user.CreatedAt.IsZero() {
user.CreatedAt = now
}
if user.ModifiedAt.IsZero() {
user.ModifiedAt = now
}
// Serialize complex data to JSON
profileDataJSON, err := impl.serializeProfileData(user.ProfileData)
if err != nil {
return fmt.Errorf("failed to serialize profile data: %w", err)
}
securityDataJSON, err := impl.serializeSecurityData(user.SecurityData)
if err != nil {
return fmt.Errorf("failed to serialize security data: %w", err)
}
metadataJSON, err := impl.serializeMetadata(user.Metadata)
if err != nil {
return fmt.Errorf("failed to serialize metadata: %w", err)
}
// Use a batch for atomic writes across multiple tables
batch := impl.session.NewBatch(gocql.LoggedBatch).WithContext(ctx)
// 1. Insert into users_by_id (primary table)
batch.Query(`
INSERT INTO users_by_id (
id, email, first_name, last_name, name, lexical_name,
role, status, timezone, created_at, modified_at,
profile_data, security_data, metadata
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
user.ID, user.Email, user.FirstName, user.LastName, user.Name, user.LexicalName,
user.Role, user.Status, user.Timezone, user.CreatedAt, user.ModifiedAt,
profileDataJSON, securityDataJSON, metadataJSON,
)
// 2. Insert into users_by_email
batch.Query(`
INSERT INTO users_by_email (
email, id, first_name, last_name, name, lexical_name,
role, status, timezone, created_at, modified_at,
profile_data, security_data, metadata
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
user.Email, user.ID, user.FirstName, user.LastName, user.Name, user.LexicalName,
user.Role, user.Status, user.Timezone, user.CreatedAt, user.ModifiedAt,
profileDataJSON, securityDataJSON, metadataJSON,
)
// 3. Insert into users_by_verification_code if verification code exists
if user.SecurityData != nil && user.SecurityData.Code != "" {
batch.Query(`
INSERT INTO users_by_verification_code (
verification_code, id, email, first_name, last_name, name, lexical_name,
role, status, timezone, created_at, modified_at,
profile_data, security_data, metadata
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
user.SecurityData.Code, user.ID, user.Email, user.FirstName, user.LastName, user.Name, user.LexicalName,
user.Role, user.Status, user.Timezone, user.CreatedAt, user.ModifiedAt,
profileDataJSON, securityDataJSON, metadataJSON,
)
}
// 4. Insert into users_by_status_and_date for listing
// Skip
// 5. If status is active, also insert into active users table
if user.Status == dom_user.UserStatusActive {
// Skip
}
// 6. Add to search index (simplified - you might want to use external search)
if user.Name != "" || user.Email != "" {
// Skip
}
// Execute the batch
if err := impl.session.ExecuteBatch(batch); err != nil {
impl.logger.Error("Failed to create user",
zap.String("user_id", user.ID.String()),
zap.String("email", validation.MaskEmail(user.Email)),
zap.Error(err))
return fmt.Errorf("failed to create user: %w", err)
}
impl.logger.Info("User created successfully",
zap.String("user_id", user.ID.String()),
zap.String("email", validation.MaskEmail(user.Email)))
return nil
}