@@ -39,27 +39,48 @@ func NewUnitRepository(db *gorm.DB, blobStore storage.UnitStore) *UnitRepository
3939
4040// Create creates a new unit with UUID and org-scoped storage
4141func (r * UnitRepository ) Create (ctx context.Context , orgID , name string ) (* storage.UnitMetadata , error ) {
42+ startRepo := time .Now ()
43+
44+ // Extract request ID from context if available (passed through from handler)
45+ requestID := "repo"
46+ if ctx .Value ("request-id" ) != nil {
47+ if rid , ok := ctx .Value ("request-id" ).(string ); ok {
48+ requestID = rid
49+ }
50+ }
51+
52+ log .Printf ("[%s] 💾 REPOSITORY: Starting Create (org: %s, name: %s)" , requestID , orgID , name )
53+
4254 // Get organization to validate and get org name
55+ orgLookupStart := time .Now ()
4356 var org types.Organization
4457 if err := r .db .WithContext (ctx ).Where (queryByID , orgID ).First (& org ).Error ; err != nil {
58+ log .Printf ("[%s] ❌ REPOSITORY: Org lookup failed (+%dms) - %v" , requestID , time .Since (startRepo ).Milliseconds (), err )
4559 if errors .Is (err , gorm .ErrRecordNotFound ) {
4660 return nil , fmt .Errorf ("organization not found: %s" , orgID )
4761 }
4862 return nil , fmt .Errorf (errMsgOrgNotFound , err )
4963 }
64+ orgLookupTime := time .Since (orgLookupStart )
65+ log .Printf ("[%s] ✅ REPOSITORY: Org found '%s' (%dms)" , requestID , org .Name , orgLookupTime .Milliseconds ())
5066
5167 // Check if unit already exists
68+ checkExistStart := time .Now ()
5269 var existing types.Unit
5370 err := r .db .WithContext (ctx ).
5471 Where ("org_id = ? AND name = ?" , orgID , name ).
5572 First (& existing ).Error
73+ checkExistTime := time .Since (checkExistStart )
5674
5775 if err == nil {
76+ log .Printf ("[%s] ⚠️ REPOSITORY: Unit already exists (check: %dms, total: %dms)" , requestID , checkExistTime .Milliseconds (), time .Since (startRepo ).Milliseconds ())
5877 return nil , storage .ErrAlreadyExists
5978 }
6079 if ! errors .Is (err , gorm .ErrRecordNotFound ) {
80+ log .Printf ("[%s] ❌ REPOSITORY: Error checking existing unit (+%dms) - %v" , requestID , time .Since (startRepo ).Milliseconds (), err )
6181 return nil , fmt .Errorf ("failed to check existing unit: %w" , err )
6282 }
83+ log .Printf ("[%s] ✅ REPOSITORY: Unit name available (check: %dms)" , requestID , checkExistTime .Milliseconds ())
6384
6485 // Create database record (UUID auto-generated by BeforeCreate hook)
6586 now := time .Now ()
@@ -71,7 +92,9 @@ func (r *UnitRepository) Create(ctx context.Context, orgID, name string) (*stora
7192 Locked : false ,
7293 }
7394
95+ dbCreateStart := time .Now ()
7496 if err := r .db .WithContext (ctx ).Create (unit ).Error ; err != nil {
97+ log .Printf ("[%s] ❌ REPOSITORY: DB create failed (attempt: %dms, total: %dms) - %v" , requestID , time .Since (dbCreateStart ).Milliseconds (), time .Since (startRepo ).Milliseconds (), err )
7598 // Check if this is a unique constraint violation
7699 // GORM doesn't have a specific error type, so we check the error string
77100 errMsg := err .Error ()
@@ -83,6 +106,8 @@ func (r *UnitRepository) Create(ctx context.Context, orgID, name string) (*stora
83106 }
84107 return nil , fmt .Errorf ("failed to create unit in database: %w" , err )
85108 }
109+ dbCreateTime := time .Since (dbCreateStart )
110+ log .Printf ("[%s] ✅ REPOSITORY: DB record created with UUID %s (db_insert: %dms)" , requestID , unit .ID , dbCreateTime .Milliseconds ())
86111
87112 // Construct UUID-based blob path: {org-uuid}/{unit-uuid}
88113 // This is immutable - unit renames won't affect S3 paths
@@ -91,20 +116,24 @@ func (r *UnitRepository) Create(ctx context.Context, orgID, name string) (*stora
91116 // Create blob in storage ASYNCHRONOUSLY for faster response
92117 // The unit is usable even if S3 isn't ready yet (first terraform apply will initialize it)
93118 go func () {
119+ s3Start := time .Now ()
94120 // Use background context to avoid cancellation
95121 bgCtx := context .Background ()
96122 _ , err := r .blobStore .Create (bgCtx , blobPath )
123+ s3Time := time .Since (s3Start )
97124 if err != nil {
98- log .Printf ("⚠️ Async S3 creation failed for unit %s (%s/%s) : %v - will be created on first use" ,
99- unit . ID , org .ID , unit . ID , err )
125+ log .Printf ("[%s] ⚠️ REPOSITORY: Async S3 creation failed for unit %s after %dms : %v - will be created on first use" ,
126+ requestID , unit .ID , s3Time . Milliseconds () , err )
100127 // Note: Unit remains in DB even if S3 fails - terraform apply will create the state file
101128 } else {
102- log .Printf ("✅ Async S3 blob created for unit %s (%s/%s)" , unit .ID , org .ID , unit .ID )
129+ log .Printf ("[%s] ✅ REPOSITORY: Async S3 blob created for unit %s (%s/%s) in %dms" ,
130+ requestID , unit .ID , org .ID , unit .ID , s3Time .Milliseconds ())
103131 }
104132 }()
105133
106- log .Printf ("Created unit: UUID=%s, Org=%s (%s), Name=%s, BlobPath=%s (S3 creating async)" ,
107- unit .ID , org .Name , org .ID , name , blobPath )
134+ totalRepoTime := time .Since (startRepo )
135+ log .Printf ("[%s] ✅ REPOSITORY: Complete - total: %dms (org_lookup: %dms, exist_check: %dms, db_insert: %dms, s3: async)" ,
136+ requestID , totalRepoTime .Milliseconds (), orgLookupTime .Milliseconds (), checkExistTime .Milliseconds (), dbCreateTime .Milliseconds ())
108137
109138 return & storage.UnitMetadata {
110139 ID : unit .ID , // UUID
0 commit comments