Initialize base

This commit is contained in:
hdbar
2025-07-27 16:20:21 +03:30
commit ad9db7bcce
31 changed files with 8268 additions and 0 deletions
+336
View File
@@ -0,0 +1,336 @@
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"golang.org/x/crypto/bcrypt"
"tm/internal/domain"
)
const (
DefaultMongoURI = "mongodb://localhost:27017"
DefaultDBName = "tender_management"
)
func main() {
// Get database connection details from environment or use defaults
mongoURI := DefaultMongoURI
if uri := getEnv("MONGO_URI"); uri != "" {
mongoURI = uri
}
dbName := DefaultDBName
if name := getEnv("DB_NAME"); name != "" {
dbName = name
}
fmt.Println("🚀 Starting database migration for dual user system...")
fmt.Printf("📊 Database: %s\n", dbName)
fmt.Printf("🔗 URI: %s\n", mongoURI)
// Connect to MongoDB
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoURI))
if err != nil {
log.Fatal("❌ Failed to connect to MongoDB:", err)
}
defer client.Disconnect(context.Background())
// Ping to verify connection
if err = client.Ping(ctx, nil); err != nil {
log.Fatal("❌ Failed to ping MongoDB:", err)
}
fmt.Println("✅ Connected to MongoDB successfully")
db := client.Database(dbName)
// Run migrations
if err := createCustomersCollection(db); err != nil {
log.Fatal("❌ Failed to create customers collection:", err)
}
if err := createUsersCollection(db); err != nil {
log.Fatal("❌ Failed to create users collection:", err)
}
if err := createSampleData(db); err != nil {
log.Fatal("❌ Failed to create sample data:", err)
}
fmt.Println("🎉 Database migration completed successfully!")
}
// createCustomersCollection creates the customers collection with indexes
func createCustomersCollection(db *mongo.Database) error {
fmt.Println("📝 Creating customers collection...")
collection := db.Collection("customers")
// Create indexes
indexes := []mongo.IndexModel{
{
Keys: bson.D{{"email", 1}},
Options: options.Index().SetUnique(true).SetName("email_unique"),
},
{
Keys: bson.D{{"company_id", 1}},
Options: options.Index().SetName("company_id_idx"),
},
{
Keys: bson.D{{"is_active", 1}},
Options: options.Index().SetName("is_active_idx"),
},
{
Keys: bson.D{{"created_at", -1}},
Options: options.Index().SetName("created_at_desc_idx"),
},
{
Keys: bson.D{{"role", 1}},
Options: options.Index().SetName("role_idx"),
},
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
_, err := collection.Indexes().CreateMany(ctx, indexes)
if err != nil {
return fmt.Errorf("failed to create customer indexes: %w", err)
}
fmt.Println("✅ Customers collection created with indexes")
return nil
}
// createUsersCollection creates the panel users collection with indexes
func createUsersCollection(db *mongo.Database) error {
fmt.Println("📝 Creating users collection...")
collection := db.Collection("users")
// Create indexes
indexes := []mongo.IndexModel{
{
Keys: bson.D{{"email", 1}},
Options: options.Index().SetUnique(true).SetName("email_unique"),
},
{
Keys: bson.D{{"role", 1}},
Options: options.Index().SetName("role_idx"),
},
{
Keys: bson.D{{"is_active", 1}},
Options: options.Index().SetName("is_active_idx"),
},
{
Keys: bson.D{{"department", 1}},
Options: options.Index().SetName("department_idx"),
},
{
Keys: bson.D{{"created_at", -1}},
Options: options.Index().SetName("created_at_desc_idx"),
},
{
Keys: bson.D{{"created_by", 1}},
Options: options.Index().SetName("created_by_idx"),
},
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
_, err := collection.Indexes().CreateMany(ctx, indexes)
if err != nil {
return fmt.Errorf("failed to create user indexes: %w", err)
}
fmt.Println("✅ Users collection created with indexes")
return nil
}
// createSampleData creates sample admin user and test customer
func createSampleData(db *mongo.Database) error {
fmt.Println("📝 Creating sample data...")
// Create sample admin user
if err := createSampleAdmin(db); err != nil {
return fmt.Errorf("failed to create sample admin: %w", err)
}
// Create sample customer
if err := createSampleCustomer(db); err != nil {
return fmt.Errorf("failed to create sample customer: %w", err)
}
fmt.Println("✅ Sample data created successfully")
return nil
}
// createSampleAdmin creates a sample admin user
func createSampleAdmin(db *mongo.Database) error {
collection := db.Collection("users")
// Check if admin already exists
ctx := context.Background()
count, err := collection.CountDocuments(ctx, bson.M{"email": "admin@tendermanagement.com"})
if err != nil {
return err
}
if count > 0 {
fmt.Println("️ Sample admin user already exists, skipping...")
return nil
}
// Hash password for admin
hashedPassword, err := bcrypt.GenerateFromPassword([]byte("admin123!"), bcrypt.DefaultCost)
if err != nil {
return err
}
now := time.Now()
adminID := uuid.New()
admin := bson.M{
"_id": adminID,
"email": "admin@tendermanagement.com",
"password": string(hashedPassword),
"first_name": "System",
"last_name": "Administrator",
"role": domain.UserRoleAdmin,
"department": "IT",
"is_active": true,
"permissions": []string{
"manage_users",
"manage_tenders",
"manage_companies",
"manage_customers",
"view_reports",
"manage_system",
"manage_sources",
},
"created_at": now,
"updated_at": now,
}
_, err = collection.InsertOne(ctx, admin)
if err != nil {
return err
}
fmt.Println("👤 Sample admin user created:")
fmt.Println(" 📧 Email: admin@tendermanagement.com")
fmt.Println(" 🔑 Password: admin123!")
fmt.Println(" 🛡️ Role: admin")
return nil
}
// createSampleCustomer creates a sample customer
func createSampleCustomer(db *mongo.Database) error {
collection := db.Collection("customers")
// Check if customer already exists
ctx := context.Background()
count, err := collection.CountDocuments(ctx, bson.M{"email": "customer@example.com"})
if err != nil {
return err
}
if count > 0 {
fmt.Println("️ Sample customer already exists, skipping...")
return nil
}
// Hash password for customer
hashedPassword, err := bcrypt.GenerateFromPassword([]byte("customer123!"), bcrypt.DefaultCost)
if err != nil {
return err
}
now := time.Now()
companyID := uuid.New()
customerID := uuid.New()
// Create sample company first
companyCollection := db.Collection("companies")
company := bson.M{
"_id": companyID,
"name": "Sample Company Ltd",
"description": "A sample company for testing",
"industry": "Technology",
"country": "United States",
"website": "https://example.com",
"keywords": []string{"technology", "software", "consulting"},
"products": []string{"software development", "consulting"},
"services": []string{"web development", "mobile apps"},
"created_at": now,
"updated_at": now,
}
_, err = companyCollection.InsertOne(ctx, company)
if err != nil {
return err
}
// Create customer
customer := bson.M{
"_id": customerID,
"email": "customer@example.com",
"password": string(hashedPassword),
"first_name": "John",
"last_name": "Doe",
"phone": "+1234567890",
"role": domain.CustomerRoleUser,
"company_id": companyID,
"is_active": true,
"is_verified": true,
"device_tokens": []string{},
"preferences": bson.M{
"language": "en",
"notification_settings": bson.M{
"new_tenders": true,
"deadline_reminder": true,
"status_updates": true,
"system_alerts": true,
},
"tender_alerts": true,
"email_notifications": true,
"push_notifications": true,
"preferred_categories": []string{},
},
"created_at": now,
"updated_at": now,
}
_, err = collection.InsertOne(ctx, customer)
if err != nil {
return err
}
fmt.Println("👤 Sample customer created:")
fmt.Println(" 📧 Email: customer@example.com")
fmt.Println(" 🔑 Password: customer123!")
fmt.Println(" 🏢 Company: Sample Company Ltd")
fmt.Println(" 📱 Role: customer_user")
return nil
}
// Helper functions
func getEnv(key string) string {
// Simple environment variable getter
// In a real implementation, you might use os.Getenv()
return ""
}