kamau1 commited on
Commit
70ac999
·
1 Parent(s): 92ba9ad

Enhance audit and project services with idempotent behavior and JSON serialization

Browse files

- Added JSON serialization support for non-serializable types in AuditService.
- Updated AuditService to sanitize changes and metadata before logging.
- Improved ProjectService to allow idempotent creation and updating of project regions, roles, and subcontractors.
- Implemented checks for existing entities to update instead of raising errors on duplicates.
- Enhanced logging for updates in ProjectService methods for better traceability.

docs/devlogs/browser/browserconsole.txt CHANGED
@@ -79,3 +79,107 @@ core.ts:117 ❌ [11:52:19] [COMPONENT] StepRegions error: An error occurred whil
79
  log @ core.ts:117
80
  core.ts:124 ⚠️ [11:52:19] [COMPONENT] ProjectSetupWizard: Step save failed
81
  log @ core.ts:124
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  log @ core.ts:117
80
  core.ts:124 ⚠️ [11:52:19] [COMPONENT] ProjectSetupWizard: Step save failed
81
  log @ core.ts:124
82
+ core.ts:167 %cGET%c https://kamau1-swiftops-backend.hf.space/api/v1/users?skip=0&limit=100
83
+ core.ts:167 GET https://kamau1-swiftops-backend.hf.space/api/v1/users?skip=0&limit=100 → 200 (5.92s)
84
+ core.ts:124 ℹ️ [12:03:20] [COMPONENT] ProjectSetupWizard: User clicked save
85
+ core.ts:117 ℹ️ [12:03:20] [COMPONENT] StepRegions: Saving regions batch {count: 1, deleted: 0}
86
+ core.ts:124 ⚠️ [12:03:20] [COMPONENT] ProjectSetupWizard: Step save failed
87
+ log @ core.ts:124
88
+ warn @ core.ts:150
89
+ warn @ component.ts:100
90
+ handleSave @ ProjectSetupWizard.tsx:115
91
+ await in handleSave
92
+ callCallback2 @ chunk-276SZO74.js?v=667b4a6e:3674
93
+ invokeGuardedCallbackDev @ chunk-276SZO74.js?v=667b4a6e:3699
94
+ invokeGuardedCallback @ chunk-276SZO74.js?v=667b4a6e:3733
95
+ invokeGuardedCallbackAndCatchFirstError @ chunk-276SZO74.js?v=667b4a6e:3736
96
+ executeDispatch @ chunk-276SZO74.js?v=667b4a6e:7014
97
+ processDispatchQueueItemsInOrder @ chunk-276SZO74.js?v=667b4a6e:7034
98
+ processDispatchQueue @ chunk-276SZO74.js?v=667b4a6e:7043
99
+ dispatchEventsForPlugins @ chunk-276SZO74.js?v=667b4a6e:7051
100
+ (anonymous) @ chunk-276SZO74.js?v=667b4a6e:7174
101
+ batchedUpdates$1 @ chunk-276SZO74.js?v=667b4a6e:18913
102
+ batchedUpdates @ chunk-276SZO74.js?v=667b4a6e:3579
103
+ dispatchEventForPluginEventSystem @ chunk-276SZO74.js?v=667b4a6e:7173
104
+ dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ chunk-276SZO74.js?v=667b4a6e:5478
105
+ dispatchEvent @ chunk-276SZO74.js?v=667b4a6e:5472
106
+ dispatchDiscreteEvent @ chunk-276SZO74.js?v=667b4a6e:5449
107
+ core.ts:124 ℹ️ [12:05:20] [COMPONENT] ProjectSetupWizard: User clicked save
108
+ core.ts:117 ℹ️ [12:05:20] [COMPONENT] StepRegions: Saving regions batch {count: 1, deleted: 0}
109
+ core.ts:167 %cPOST%c https://kamau1-swiftops-backend.hf.space/api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions
110
+ core.ts:167 POST https://kamau1-swiftops-backend.hf.space/api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions → 201 (2.80s)
111
+ core.ts:167 %cGET%c https://kamau1-swiftops-backend.hf.space/api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions
112
+ core.ts:167 GET https://kamau1-swiftops-backend.hf.space/api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions → 200 (357ms)
113
+ ProjectSetupContext.tsx:32 🔧 ProjectSetupProvider RENDERING
114
+ ProjectSetupContext.tsx:38 🔧 ProjectSetupProvider projectId: 0ade6bd1-e492-4e25-b681-59f42058d29a
115
+ ProjectSetupContext.tsx:64 🔧 Project query state: {isLoadingProject: false, hasProject: true, error: null}
116
+ ProjectSetupWizard.tsx:38 🎯 ProjectSetupContent RENDER: {isLoadingProject: false, hasProject: true}
117
+ core.ts:124 ℹ️ [12:06:28] [COMPONENT] ProjectSetupWizard: User clicked save
118
+ core.ts:117 ℹ️ [12:06:28] [COMPONENT] StepRegions: Saving regions batch {count: 1, deleted: 0}
119
+ core.ts:167 %cPATCH%c https://kamau1-swiftops-backend.hf.space/api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions/4cd27765-5720-4cc0-872e-bf0da3cd1898
120
+ project-setup.service.ts:185 PATCH https://kamau1-swiftops-backend.hf.space/api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions/4cd27765-5720-4cc0-872e-bf0da3cd1898 500 (Internal Server Error)
121
+ updateRegion @ project-setup.service.ts:185
122
+ (anonymous) @ StepRegions.tsx:333
123
+ save @ StepRegions.tsx:298
124
+ handleSave @ ProjectSetupWizard.tsx:111
125
+ callCallback2 @ chunk-276SZO74.js?v=667b4a6e:3674
126
+ invokeGuardedCallbackDev @ chunk-276SZO74.js?v=667b4a6e:3699
127
+ invokeGuardedCallback @ chunk-276SZO74.js?v=667b4a6e:3733
128
+ invokeGuardedCallbackAndCatchFirstError @ chunk-276SZO74.js?v=667b4a6e:3736
129
+ executeDispatch @ chunk-276SZO74.js?v=667b4a6e:7014
130
+ processDispatchQueueItemsInOrder @ chunk-276SZO74.js?v=667b4a6e:7034
131
+ processDispatchQueue @ chunk-276SZO74.js?v=667b4a6e:7043
132
+ dispatchEventsForPlugins @ chunk-276SZO74.js?v=667b4a6e:7051
133
+ (anonymous) @ chunk-276SZO74.js?v=667b4a6e:7174
134
+ batchedUpdates$1 @ chunk-276SZO74.js?v=667b4a6e:18913
135
+ batchedUpdates @ chunk-276SZO74.js?v=667b4a6e:3579
136
+ dispatchEventForPluginEventSystem @ chunk-276SZO74.js?v=667b4a6e:7173
137
+ dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ chunk-276SZO74.js?v=667b4a6e:5478
138
+ dispatchEvent @ chunk-276SZO74.js?v=667b4a6e:5472
139
+ dispatchDiscreteEvent @ chunk-276SZO74.js?v=667b4a6e:5449
140
+ core.ts:167 PATCH https://kamau1-swiftops-backend.hf.space/api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions/4cd27765-5720-4cc0-872e-bf0da3cd1898 → 500 (1.54s)
141
+ core.ts:117 ❌ [12:06:29] [COMPONENT] StepRegions error: An error occurred while updating the region {error: Error: An error occurred while updating the region
142
+ at handleResponse (http://localhost:8080/src…, errorInfo: {…}}
143
+ log @ core.ts:117
144
+ error @ core.ts:157
145
+ logComponentError @ component.ts:60
146
+ error @ component.ts:96
147
+ save @ StepRegions.tsx:342
148
+ await in save
149
+ handleSave @ ProjectSetupWizard.tsx:111
150
+ callCallback2 @ chunk-276SZO74.js?v=667b4a6e:3674
151
+ invokeGuardedCallbackDev @ chunk-276SZO74.js?v=667b4a6e:3699
152
+ invokeGuardedCallback @ chunk-276SZO74.js?v=667b4a6e:3733
153
+ invokeGuardedCallbackAndCatchFirstError @ chunk-276SZO74.js?v=667b4a6e:3736
154
+ executeDispatch @ chunk-276SZO74.js?v=667b4a6e:7014
155
+ processDispatchQueueItemsInOrder @ chunk-276SZO74.js?v=667b4a6e:7034
156
+ processDispatchQueue @ chunk-276SZO74.js?v=667b4a6e:7043
157
+ dispatchEventsForPlugins @ chunk-276SZO74.js?v=667b4a6e:7051
158
+ (anonymous) @ chunk-276SZO74.js?v=667b4a6e:7174
159
+ batchedUpdates$1 @ chunk-276SZO74.js?v=667b4a6e:18913
160
+ batchedUpdates @ chunk-276SZO74.js?v=667b4a6e:3579
161
+ dispatchEventForPluginEventSystem @ chunk-276SZO74.js?v=667b4a6e:7173
162
+ dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ chunk-276SZO74.js?v=667b4a6e:5478
163
+ dispatchEvent @ chunk-276SZO74.js?v=667b4a6e:5472
164
+ dispatchDiscreteEvent @ chunk-276SZO74.js?v=667b4a6e:5449
165
+ core.ts:124 ⚠️ [12:06:29] [COMPONENT] ProjectSetupWizard: Step save failed
166
+ log @ core.ts:124
167
+ warn @ core.ts:150
168
+ warn @ component.ts:100
169
+ handleSave @ ProjectSetupWizard.tsx:115
170
+ await in handleSave
171
+ callCallback2 @ chunk-276SZO74.js?v=667b4a6e:3674
172
+ invokeGuardedCallbackDev @ chunk-276SZO74.js?v=667b4a6e:3699
173
+ invokeGuardedCallback @ chunk-276SZO74.js?v=667b4a6e:3733
174
+ invokeGuardedCallbackAndCatchFirstError @ chunk-276SZO74.js?v=667b4a6e:3736
175
+ executeDispatch @ chunk-276SZO74.js?v=667b4a6e:7014
176
+ processDispatchQueueItemsInOrder @ chunk-276SZO74.js?v=667b4a6e:7034
177
+ processDispatchQueue @ chunk-276SZO74.js?v=667b4a6e:7043
178
+ dispatchEventsForPlugins @ chunk-276SZO74.js?v=667b4a6e:7051
179
+ (anonymous) @ chunk-276SZO74.js?v=667b4a6e:7174
180
+ batchedUpdates$1 @ chunk-276SZO74.js?v=667b4a6e:18913
181
+ batchedUpdates @ chunk-276SZO74.js?v=667b4a6e:3579
182
+ dispatchEventForPluginEventSystem @ chunk-276SZO74.js?v=667b4a6e:7173
183
+ dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ chunk-276SZO74.js?v=667b4a6e:5478
184
+ dispatchEvent @ chunk-276SZO74.js?v=667b4a6e:5472
185
+ dispatchDiscreteEvent @ chunk-276SZO74.js?v=667b4a6e:5449
docs/devlogs/server/runtimeerror.txt CHANGED
@@ -1,497 +1,142 @@
1
- ===== Application Startup at 2025-11-22 18:00:19 =====
2
 
3
  INFO: Started server process [7]
4
  INFO: Waiting for application startup.
5
- INFO: 2025-11-22T18:00:34 - app.main: ============================================================
6
- INFO: 2025-11-22T18:00:34 - app.main: 🚀 SwiftOps API v1.0.0 | PRODUCTION
7
- INFO: 2025-11-22T18:00:34 - app.main: ============================================================
8
- INFO: 2025-11-22T18:00:34 - app.main: 📦 Database:
9
- INFO: 2025-11-22T18:00:34 - app.main: ✓ Connected | 44 tables | 5 users
10
- INFO: 2025-11-22T18:00:34 - app.main: 💾 Cache & Sessions:
11
- INFO: 2025-11-22T18:00:35 - app.services.otp_service: ✅ OTP Service initialized with Redis storage
12
- INFO: 2025-11-22T18:00:35 - app.main: ✓ Redis: Connected
13
- INFO: 2025-11-22T18:00:35 - app.main: 🔌 External Services:
14
- INFO: 2025-11-22T18:00:36 - app.main: ✓ Cloudinary: Connected
15
- INFO: 2025-11-22T18:00:36 - app.main: ✓ Resend: Configured
16
- INFO: 2025-11-22T18:00:36 - app.main: ✓ WASender: Connected
17
- INFO: 2025-11-22T18:00:36 - app.main: ✓ Supabase: Connected | 6 buckets
18
- INFO: 2025-11-22T18:00:36 - app.main: ============================================================
19
- INFO: 2025-11-22T18:00:36 - app.main: ✅ Startup complete | Ready to serve requests
20
- INFO: 2025-11-22T18:00:36 - app.main: ============================================================
21
  INFO: Application startup complete.
 
 
 
 
 
 
 
22
  INFO: Uvicorn running on http://0.0.0.0:7860 (Press CTRL+C to quit)
23
- INFO: 10.16.44.15:53714 - "GET /health HTTP/1.1" 200 OK
24
- INFO: 10.16.44.15:65447 - "GET / HTTP/1.1" 200 OK
25
- INFO: 10.16.44.15:21256 - "GET /health HTTP/1.1" 200 OK
26
- INFO: 10.16.44.15:34351 - "GET /health HTTP/1.1" 200 OK
27
- INFO: 2025-11-22T18:23:58 - app.core.supabase_auth: User signed in successfully: nadina73@nembors.com
28
- INFO: 2025-11-22T18:23:59 - app.services.audit_service: Audit log created: login on auth by nadina73@nembors.com
29
- INFO: 2025-11-22T18:23:59 - app.api.v1.auth: User logged in successfully: nadina73@nembors.com
30
- INFO: 10.16.18.114:58215 - "POST /api/v1/auth/login HTTP/1.1" 200 OK
31
- INFO: 10.16.18.114:58215 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
32
- INFO: 10.16.18.114:58215 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
33
- INFO: 10.16.18.108:23438 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
34
- INFO: 10.16.44.15:25468 - "GET /api/v1/projects?page=1&per_page=100 HTTP/1.1" 200 OK
35
- INFO: 10.16.13.195:7949 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a HTTP/1.1" 200 OK
36
- INFO: 10.16.13.195:62885 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions HTTP/1.1" 200 OK
37
- INFO: 10.16.18.114:30559 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/project-roles HTTP/1.1" 200 OK
38
- INFO: 10.16.18.114:17027 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/subcontractors HTTP/1.1" 200 OK
39
- INFO: 10.16.18.108:1569 - "GET /api/v1/users?skip=0&limit=100 HTTP/1.1" 200 OK
40
- INFO: 10.16.44.15:35493 - "GET /health HTTP/1.1" 200 OK
41
- INFO: 10.16.44.15:46124 - "GET /health HTTP/1.1" 200 OK
42
- INFO: 10.16.8.187:29172 - "GET /health HTTP/1.1" 200 OK
43
- INFO: 10.16.8.187:16209 - "GET /health HTTP/1.1" 200 OK
44
- INFO: 10.16.44.15:34400 - "GET /api/v1/users?skip=0&limit=100 HTTP/1.1" 200 OK
45
- INFO: 10.16.18.108:61055 - "GET /health HTTP/1.1" 200 OK
46
- INFO: 10.16.44.15:51645 - "GET /health HTTP/1.1" 200 OK
47
- INFO: 10.16.44.15:51645 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
48
- INFO: 10.16.18.108:38391 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a HTTP/1.1" 200 OK
49
- INFO: 10.16.44.15:51645 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/subcontractors HTTP/1.1" 200 OK
50
- INFO: 10.16.8.187:49901 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/project-roles HTTP/1.1" 200 OK
51
- INFO: 10.16.8.187:23494 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
52
- INFO: 10.16.8.187:4626 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
53
- INFO: 10.16.8.187:17122 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions HTTP/1.1" 200 OK
54
- INFO: 10.16.18.108:22542 - "GET /api/v1/users?skip=0&limit=100 HTTP/1.1" 200 OK
55
- INFO: 10.16.44.15:29731 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
56
- INFO: 10.16.18.108:48542 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
57
- INFO: 10.16.18.108:1590 - "GET /health HTTP/1.1" 200 OK
58
- INFO: 10.16.18.114:47765 - "GET /api/v1/users?skip=0&limit=100 HTTP/1.1" 200 OK
59
- INFO: 10.16.44.15:40779 - "GET /api/v1/users?skip=0&limit=100 HTTP/1.1" 200 OK
60
- INFO: 10.16.8.187:54230 - "GET /health HTTP/1.1" 200 OK
61
- INFO: 10.16.8.187:35857 - "GET /health HTTP/1.1" 200 OK
62
- INFO: 10.16.44.15:2962 - "GET /api/v1/users?skip=0&limit=100 HTTP/1.1" 200 OK
63
- INFO: 10.16.44.15:2962 - "GET /api/v1/users?skip=0&limit=100 HTTP/1.1" 200 OK
64
- INFO: 10.16.18.108:9990 - "GET /api/v1/users?skip=0&limit=100 HTTP/1.1" 200 OK
65
- INFO: 10.16.8.187:1974 - "GET /health HTTP/1.1" 200 OK
66
- INFO: 10.16.18.114:1106 - "GET /api/v1/users?skip=0&limit=100 HTTP/1.1" 200 OK
67
- INFO: 10.16.8.187:37417 - "GET /health HTTP/1.1" 200 OK
68
- INFO: 10.16.8.187:56330 - "GET /health HTTP/1.1" 200 OK
69
- INFO: 10.16.8.187:32884 - "GET /health HTTP/1.1" 200 OK
70
- INFO: 10.16.18.114:7467 - "GET /health HTTP/1.1" 200 OK
71
- INFO: 10.16.18.114:9116 - "GET /api/v1/users?skip=0&limit=100 HTTP/1.1" 200 OK
72
- INFO: 10.16.18.108:10926 - "GET /api/v1/users?skip=0&limit=100 HTTP/1.1" 200 OK
73
- INFO: 10.16.18.114:38310 - "GET /api/v1/users?skip=0&limit=100 HTTP/1.1" 200 OK
74
- INFO: 10.16.18.114:38310 - "GET /health HTTP/1.1" 200 OK
75
- INFO: 10.16.44.15:54392 - "GET /health HTTP/1.1" 200 OK
76
- INFO: 10.16.18.114:61325 - "GET /health HTTP/1.1" 200 OK
77
- INFO: 10.16.18.108:33447 - "GET /health HTTP/1.1" 200 OK
78
- INFO: 10.16.18.108:33447 - "GET /health HTTP/1.1" 200 OK
79
- INFO: 10.16.18.114:3186 - "GET /health HTTP/1.1" 200 OK
80
- INFO: 10.16.18.108:52684 - "GET /health HTTP/1.1" 200 OK
81
- INFO: 10.16.44.15:11124 - "GET /health HTTP/1.1" 200 OK
82
- INFO: 10.16.18.108:34673 - "GET /health HTTP/1.1" 200 OK
83
- INFO: 10.16.18.114:21724 - "GET /health HTTP/1.1" 200 OK
84
- INFO: 10.16.8.187:33035 - "GET /health HTTP/1.1" 200 OK
85
- INFO: 10.16.8.187:49845 - "GET /health HTTP/1.1" 200 OK
86
- INFO: 10.16.44.15:38344 - "GET /health HTTP/1.1" 200 OK
87
- INFO: 10.16.18.114:40008 - "GET /health HTTP/1.1" 200 OK
88
- INFO: 10.16.8.187:62565 - "GET /health HTTP/1.1" 200 OK
89
- INFO: 10.16.18.108:40122 - "GET /health HTTP/1.1" 200 OK
90
- INFO: 10.16.18.108:40122 - "GET /health HTTP/1.1" 200 OK
91
- INFO: 2025-11-22T19:03:07 - app.core.supabase_auth: User signed in successfully: nadina73@nembors.com
92
- INFO: 2025-11-22T19:03:07 - app.services.audit_service: Audit log created: login on auth by nadina73@nembors.com
93
- INFO: 2025-11-22T19:03:07 - app.api.v1.auth: User logged in successfully: nadina73@nembors.com
94
- INFO: 10.16.18.114:29281 - "POST /api/v1/auth/login HTTP/1.1" 200 OK
95
- INFO: 10.16.44.15:33866 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
96
- INFO: 10.16.44.15:33866 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
97
- INFO: 10.16.18.108:41476 - "GET /api/v1/projects?page=1&per_page=100 HTTP/1.1" 200 OK
98
- INFO: 10.16.18.114:29281 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
99
- INFO: 10.16.18.114:36296 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/subcontractors HTTP/1.1" 200 OK
100
- INFO: 10.16.18.114:4628 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/project-roles HTTP/1.1" 200 OK
101
- INFO: 10.16.44.15:9748 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a HTTP/1.1" 200 OK
102
- INFO: 10.16.44.15:37923 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions HTTP/1.1" 200 OK
103
- INFO: 10.16.44.15:46098 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
104
- INFO: 10.16.18.108:39475 - "GET /health HTTP/1.1" 200 OK
105
- INFO: 10.16.18.108:39475 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/subcontractors HTTP/1.1" 200 OK
106
- INFO: 10.16.44.15:46098 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
107
- INFO: 10.16.8.187:8901 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions HTTP/1.1" 200 OK
108
- INFO: 10.16.18.114:55961 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
109
- INFO: 10.16.18.114:48253 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/project-roles HTTP/1.1" 200 OK
110
- INFO: 10.16.18.114:64903 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a HTTP/1.1" 200 OK
111
- INFO: 10.16.8.187:47614 - "GET /health HTTP/1.1" 200 OK
112
- INFO: 10.16.18.114:22217 - "GET /health HTTP/1.1" 200 OK
113
- INFO: 10.16.18.114:63312 - "GET /health HTTP/1.1" 200 OK
114
- INFO: 10.16.8.187:24090 - "GET /health HTTP/1.1" 200 OK
115
- INFO: 10.16.18.114:33563 - "GET /health HTTP/1.1" 200 OK
116
- INFO: 10.16.44.15:8854 - "GET /health HTTP/1.1" 200 OK
117
- INFO: 10.16.44.15:23261 - "GET /health HTTP/1.1" 200 OK
118
- INFO: 10.16.18.114:7210 - "GET /health HTTP/1.1" 200 OK
119
- INFO: 10.16.8.187:48934 - "GET /health HTTP/1.1" 200 OK
120
- INFO: 10.16.8.187:41363 - "GET /health HTTP/1.1" 200 OK
121
- INFO: 10.16.8.187:39226 - "GET /health HTTP/1.1" 200 OK
122
- INFO: 10.16.18.114:35192 - "GET /health HTTP/1.1" 200 OK
123
- INFO: 10.16.44.15:56436 - "GET /health HTTP/1.1" 200 OK
124
- INFO: 10.16.18.114:9909 - "GET /health HTTP/1.1" 200 OK
125
- INFO: 10.16.8.187:22454 - "GET /health HTTP/1.1" 200 OK
126
- INFO: 10.16.18.114:1258 - "GET /health HTTP/1.1" 200 OK
127
- INFO: 10.16.44.15:26969 - "GET /health HTTP/1.1" 200 OK
128
- INFO: 10.16.18.114:54433 - "GET /health HTTP/1.1" 200 OK
129
- INFO: 10.16.18.114:57807 - "GET /health HTTP/1.1" 200 OK
130
- INFO: 10.16.18.108:52920 - "GET /health HTTP/1.1" 200 OK
131
- INFO: 10.16.18.108:61390 - "GET /health HTTP/1.1" 200 OK
132
- INFO: 10.16.18.114:12688 - "GET /health HTTP/1.1" 200 OK
133
- INFO: 10.16.18.108:62801 - "GET /health HTTP/1.1" 200 OK
134
- INFO: 10.16.8.187:26732 - "GET /health HTTP/1.1" 200 OK
135
- INFO: 10.16.18.108:17463 - "GET /health HTTP/1.1" 200 OK
136
- INFO: 10.16.8.187:37995 - "GET /health HTTP/1.1" 200 OK
137
- INFO: 10.16.18.114:1506 - "GET /health HTTP/1.1" 200 OK
138
- INFO: 10.16.44.15:12184 - "GET /health HTTP/1.1" 200 OK
139
- INFO: 10.16.18.114:11764 - "GET /health HTTP/1.1" 200 OK
140
- INFO: 10.16.44.15:3795 - "GET /health HTTP/1.1" 200 OK
141
- INFO: 10.16.18.114:12155 - "GET /health HTTP/1.1" 200 OK
142
- INFO: 10.16.18.108:50266 - "GET /health HTTP/1.1" 200 OK
143
- INFO: 10.16.18.108:40805 - "GET /health HTTP/1.1" 200 OK
144
- INFO: 10.16.44.194:60620 - "GET /health HTTP/1.1" 200 OK
145
- INFO: 10.16.8.187:52392 - "GET /health HTTP/1.1" 200 OK
146
- INFO: 10.16.18.108:13222 - "GET /health HTTP/1.1" 200 OK
147
- INFO: 10.16.44.194:62405 - "GET /health HTTP/1.1" 200 OK
148
- INFO: 10.16.44.15:3899 - "GET /health HTTP/1.1" 200 OK
149
- INFO: 10.16.18.114:1340 - "GET /health HTTP/1.1" 200 OK
150
- INFO: 10.16.44.15:18046 - "GET /health HTTP/1.1" 200 OK
151
- INFO: 10.16.44.15:50103 - "GET /health HTTP/1.1" 200 OK
152
- INFO: 10.16.18.114:59272 - "GET /health HTTP/1.1" 200 OK
153
- INFO: 10.16.18.114:60787 - "GET /health HTTP/1.1" 200 OK
154
- INFO: 10.16.8.187:18700 - "GET /health HTTP/1.1" 200 OK
155
- INFO: 10.16.18.114:25281 - "GET /health HTTP/1.1" 200 OK
156
- INFO: 10.16.8.187:10998 - "GET /health HTTP/1.1" 200 OK
157
- INFO: 10.16.18.108:20400 - "GET /health HTTP/1.1" 200 OK
158
- INFO: 10.16.8.187:65064 - "GET /health HTTP/1.1" 200 OK
159
- INFO: 10.16.18.114:48810 - "GET /health HTTP/1.1" 200 OK
160
- INFO: 10.16.18.114:50645 - "GET /health HTTP/1.1" 200 OK
161
- INFO: 10.16.18.108:52985 - "GET /health HTTP/1.1" 200 OK
162
- INFO: 10.16.8.187:64454 - "GET /health HTTP/1.1" 200 OK
163
- INFO: 10.16.8.187:22440 - "GET /health HTTP/1.1" 200 OK
164
- INFO: 10.16.8.187:13885 - "GET /health HTTP/1.1" 200 OK
165
- INFO: 2025-11-22T19:58:10 - app.core.supabase_auth: Session refreshed successfully
166
- INFO: 2025-11-22T19:58:10 - app.api.v1.auth: ✅ Token refreshed successfully for: nadina73@nembors.com
167
- INFO: 10.16.44.15:34817 - "POST /api/v1/auth/refresh-token HTTP/1.1" 200 OK
168
- ERROR: 2025-11-22T21:58:23 - app.core.supabase_auth: Session refresh error: Invalid Refresh Token: Already Used
169
- ERROR: 2025-11-22T21:58:23 - app.api.v1.auth: ❌ Token refresh error: Invalid Refresh Token: Already Used
170
- INFO: 10.16.18.114:24179 - "POST /api/v1/auth/refresh-token HTTP/1.1" 401 Unauthorized
171
- ERROR: 2025-11-22T21:58:23 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
172
- WARNING: 2025-11-22T21:58:23 - app.api.deps: Invalid or expired token
173
- INFO: 10.16.18.114:24179 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a HTTP/1.1" 401 Unauthorized
174
- ERROR: 2025-11-22T21:58:23 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
175
- WARNING: 2025-11-22T21:58:23 - app.api.deps: Invalid or expired token
176
- ERROR: 2025-11-22T21:58:23 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
177
- WARNING: 2025-11-22T21:58:23 - app.api.deps: Invalid or expired token
178
- ERROR: 2025-11-22T21:58:23 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
179
- WARNING: 2025-11-22T21:58:23 - app.api.deps: Invalid or expired token
180
- INFO: 10.16.44.15:55275 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/project-roles HTTP/1.1" 401 Unauthorized
181
- INFO: 10.16.8.187:1842 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/subcontractors HTTP/1.1" 401 Unauthorized
182
- INFO: 10.16.18.108:54427 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions HTTP/1.1" 401 Unauthorized
183
- INFO: 10.16.18.108:41715 - "GET /health HTTP/1.1" 200 OK
184
- INFO: 10.16.18.108:54857 - "GET /health HTTP/1.1" 200 OK
185
- INFO: 10.16.8.187:41659 - "GET /health HTTP/1.1" 200 OK
186
- INFO: 10.16.44.15:10392 - "GET /health HTTP/1.1" 200 OK
187
- INFO: 10.16.18.108:63508 - "GET /health HTTP/1.1" 200 OK
188
- INFO: 10.16.18.114:23968 - "GET /health HTTP/1.1" 200 OK
189
- INFO: 10.16.8.187:32430 - "GET /health HTTP/1.1" 200 OK
190
- INFO: 10.16.44.15:50528 - "GET /health HTTP/1.1" 200 OK
191
- INFO: 10.16.18.108:25331 - "GET /health HTTP/1.1" 200 OK
192
- INFO: 10.16.8.187:37098 - "GET /health HTTP/1.1" 200 OK
193
- INFO: 10.16.18.108:56330 - "GET /health HTTP/1.1" 200 OK
194
- INFO: 10.16.18.108:35962 - "GET /health HTTP/1.1" 200 OK
195
- INFO: 10.16.18.114:5222 - "GET /health HTTP/1.1" 200 OK
196
- INFO: 10.16.18.108:51692 - "GET /health HTTP/1.1" 200 OK
197
- INFO: 10.16.44.15:56181 - "GET /health HTTP/1.1" 200 OK
198
- INFO: 10.16.18.114:36800 - "GET /health HTTP/1.1" 200 OK
199
- INFO: 10.16.8.187:51891 - "GET /health HTTP/1.1" 200 OK
200
- INFO: 10.16.18.108:6533 - "GET /health HTTP/1.1" 200 OK
201
- INFO: 10.16.18.114:22105 - "GET /health HTTP/1.1" 200 OK
202
- INFO: 10.16.8.187:37091 - "GET /health HTTP/1.1" 200 OK
203
- INFO: 10.16.44.15:48159 - "GET /health HTTP/1.1" 200 OK
204
- INFO: 10.16.8.187:52629 - "GET /health HTTP/1.1" 200 OK
205
- INFO: 10.16.18.114:31791 - "GET /health HTTP/1.1" 200 OK
206
- INFO: 10.16.18.114:21416 - "GET /health HTTP/1.1" 200 OK
207
- INFO: 10.16.8.187:23803 - "GET / HTTP/1.1" 200 OK
208
- INFO: 10.16.18.114:46720 - "GET /health HTTP/1.1" 200 OK
209
- INFO: 10.16.18.108:61489 - "GET /health HTTP/1.1" 200 OK
210
- INFO: 10.16.44.15:40747 - "GET /health HTTP/1.1" 200 OK
211
- INFO: 10.16.44.15:13086 - "GET /health HTTP/1.1" 200 OK
212
- INFO: 10.16.18.108:40077 - "GET /health HTTP/1.1" 200 OK
213
- INFO: 10.16.18.114:60551 - "GET /health HTTP/1.1" 200 OK
214
- INFO: 10.16.44.15:19838 - "GET /health HTTP/1.1" 200 OK
215
- INFO: 10.16.8.187:37927 - "GET /health HTTP/1.1" 200 OK
216
- INFO: 10.16.18.108:23352 - "GET /health HTTP/1.1" 200 OK
217
- INFO: 10.16.8.187:54048 - "GET /health HTTP/1.1" 200 OK
218
- INFO: 10.16.18.108:52629 - "GET /health HTTP/1.1" 200 OK
219
- INFO: 10.16.18.114:62010 - "GET /health HTTP/1.1" 200 OK
220
- INFO: 10.16.44.15:49502 - "GET /health HTTP/1.1" 200 OK
221
- INFO: 10.16.18.108:57198 - "GET /health HTTP/1.1" 200 OK
222
- INFO: 10.16.18.114:43767 - "GET /health HTTP/1.1" 200 OK
223
- INFO: 10.16.8.187:15804 - "GET /health HTTP/1.1" 200 OK
224
- INFO: 10.16.8.187:25376 - "GET /health HTTP/1.1" 200 OK
225
- INFO: 10.16.44.15:46638 - "GET /health HTTP/1.1" 200 OK
226
- INFO: 10.16.18.108:46491 - "GET /health HTTP/1.1" 200 OK
227
- INFO: 10.16.44.15:19865 - "GET /health HTTP/1.1" 200 OK
228
- INFO: 10.16.18.108:37182 - "GET /health HTTP/1.1" 200 OK
229
- INFO: 10.16.8.187:46293 - "GET /health HTTP/1.1" 200 OK
230
- INFO: 10.16.44.15:21732 - "GET /health HTTP/1.1" 200 OK
231
- INFO: 10.16.8.187:51985 - "GET /health HTTP/1.1" 200 OK
232
- INFO: 10.16.44.15:22461 - "GET /health HTTP/1.1" 200 OK
233
- INFO: 10.16.18.114:25438 - "GET /health HTTP/1.1" 200 OK
234
- INFO: 10.16.8.187:4442 - "GET /health HTTP/1.1" 200 OK
235
- INFO: 10.16.18.114:49578 - "GET /health HTTP/1.1" 200 OK
236
- INFO: 10.16.44.15:41653 - "GET /health HTTP/1.1" 200 OK
237
- INFO: 10.16.44.15:53577 - "GET /health HTTP/1.1" 200 OK
238
- INFO: 10.16.44.15:55037 - "GET /health HTTP/1.1" 200 OK
239
- INFO: 10.16.18.114:41616 - "GET /health HTTP/1.1" 200 OK
240
- INFO: 10.16.8.187:28737 - "GET /health HTTP/1.1" 200 OK
241
- INFO: 2025-11-23T08:08:42 - app.core.supabase_auth: Session refreshed successfully
242
- INFO: 2025-11-23T08:08:43 - app.api.v1.auth: ✅ Token refreshed successfully for: nadina73@nembors.com
243
- INFO: 10.16.44.15:25867 - "POST /api/v1/auth/refresh-token HTTP/1.1" 200 OK
244
- INFO: 10.16.18.108:28337 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
245
- INFO: 10.16.18.108:28337 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/project-roles HTTP/1.1" 200 OK
246
- INFO: 10.16.8.187:16053 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
247
- INFO: 10.16.18.108:26558 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/subcontractors HTTP/1.1" 200 OK
248
- INFO: 10.16.18.108:54710 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions HTTP/1.1" 200 OK
249
- INFO: 10.16.18.108:31143 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
250
- INFO: 10.16.8.187:51191 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a HTTP/1.1" 200 OK
251
- INFO: 10.16.8.187:2848 - "GET /health HTTP/1.1" 200 OK
252
- INFO: 10.16.18.108:48538 - "GET /health HTTP/1.1" 200 OK
253
- INFO: 10.16.8.187:25783 - "GET /health HTTP/1.1" 200 OK
254
- INFO: 10.16.44.15:49117 - "GET /health HTTP/1.1" 200 OK
255
- INFO: 10.16.18.108:2095 - "GET /health HTTP/1.1" 200 OK
256
- INFO: 10.16.8.187:9641 - "GET /health HTTP/1.1" 200 OK
257
- INFO: 10.16.18.108:15397 - "GET /health HTTP/1.1" 200 OK
258
- INFO: 10.16.18.108:16133 - "GET /health HTTP/1.1" 200 OK
259
- INFO: 10.16.18.108:36093 - "GET /health HTTP/1.1" 200 OK
260
- INFO: 10.16.18.114:50507 - "GET /health HTTP/1.1" 200 OK
261
- INFO: 10.16.18.114:20179 - "GET /health HTTP/1.1" 200 OK
262
- INFO: 10.16.44.15:12476 - "GET /health HTTP/1.1" 200 OK
263
- INFO: 10.16.44.15:60016 - "GET /health HTTP/1.1" 200 OK
264
- INFO: 10.16.18.114:42790 - "GET /health HTTP/1.1" 200 OK
265
- INFO: 10.16.8.187:41386 - "GET /health HTTP/1.1" 200 OK
266
- INFO: 10.16.18.114:17993 - "GET /health HTTP/1.1" 200 OK
267
- INFO: 10.16.18.108:41672 - "GET /health HTTP/1.1" 200 OK
268
- INFO: 10.16.18.108:26641 - "GET /health HTTP/1.1" 200 OK
269
- INFO: 10.16.18.108:20478 - "GET /health HTTP/1.1" 200 OK
270
- INFO: 10.16.44.15:41814 - "GET /health HTTP/1.1" 200 OK
271
- INFO: 10.16.18.108:14685 - "GET /health HTTP/1.1" 200 OK
272
- INFO: 10.16.44.15:8921 - "GET /health HTTP/1.1" 200 OK
273
- INFO: 10.16.8.187:57258 - "GET /health HTTP/1.1" 200 OK
274
- INFO: 10.16.8.187:30590 - "GET /health HTTP/1.1" 200 OK
275
- INFO: 10.16.8.187:5234 - "GET /health HTTP/1.1" 200 OK
276
- INFO: 10.16.44.15:44365 - "GET /health HTTP/1.1" 200 OK
277
- INFO: 10.16.18.108:5753 - "GET /health HTTP/1.1" 200 OK
278
- INFO: 10.16.18.114:46046 - "GET /health HTTP/1.1" 200 OK
279
- INFO: 10.16.8.187:19857 - "GET /health HTTP/1.1" 200 OK
280
- INFO: 10.16.8.187:12503 - "GET /health HTTP/1.1" 200 OK
281
- INFO: 10.16.44.194:3458 - "GET /health HTTP/1.1" 200 OK
282
- INFO: 10.16.8.187:28157 - "GET /health HTTP/1.1" 200 OK
283
- INFO: 10.16.18.108:61058 - "GET /health HTTP/1.1" 200 OK
284
- INFO: 10.16.18.114:46728 - "GET /health HTTP/1.1" 200 OK
285
- INFO: 10.16.18.114:15733 - "GET /health HTTP/1.1" 200 OK
286
- INFO: 10.16.8.187:37974 - "GET /health HTTP/1.1" 200 OK
287
- INFO: 10.16.18.108:44837 - "GET /health HTTP/1.1" 200 OK
288
- INFO: 10.16.18.114:64479 - "GET /health HTTP/1.1" 200 OK
289
- INFO: 10.16.18.114:41813 - "GET /health HTTP/1.1" 200 OK
290
- INFO: 10.16.8.187:18792 - "GET /health HTTP/1.1" 200 OK
291
- INFO: 10.16.44.15:3692 - "GET /health HTTP/1.1" 200 OK
292
- INFO: 10.16.18.114:31154 - "GET /health HTTP/1.1" 200 OK
293
- INFO: 10.16.44.15:65485 - "GET /health HTTP/1.1" 200 OK
294
- INFO: 10.16.8.187:2458 - "GET /health HTTP/1.1" 200 OK
295
- INFO: 10.16.44.15:34020 - "GET /health HTTP/1.1" 200 OK
296
- INFO: 10.16.44.15:43720 - "GET /health HTTP/1.1" 200 OK
297
- INFO: 10.16.18.108:61989 - "GET /health HTTP/1.1" 200 OK
298
- INFO: 10.16.18.108:48041 - "GET /health HTTP/1.1" 200 OK
299
- INFO: 10.16.8.187:51679 - "GET /health HTTP/1.1" 200 OK
300
- INFO: 10.16.18.108:58116 - "GET /health HTTP/1.1" 200 OK
301
- INFO: 10.16.8.187:14820 - "GET /health HTTP/1.1" 200 OK
302
- INFO: 10.16.18.114:43169 - "GET /health HTTP/1.1" 200 OK
303
- INFO: 10.16.44.15:43886 - "GET /health HTTP/1.1" 200 OK
304
- INFO: 10.16.44.15:45078 - "GET /health HTTP/1.1" 200 OK
305
- INFO: 2025-11-23T09:03:45 - app.core.supabase_auth: Session refreshed successfully
306
- INFO: 2025-11-23T09:03:45 - app.api.v1.auth: ✅ Token refreshed successfully for: nadina73@nembors.com
307
- INFO: 10.16.44.15:62381 - "POST /api/v1/auth/refresh-token HTTP/1.1" 200 OK
308
- INFO: 10.16.8.187:47598 - "GET /health HTTP/1.1" 200 OK
309
- INFO: 10.16.18.108:28967 - "GET /health HTTP/1.1" 200 OK
310
- INFO: 10.16.18.114:52274 - "GET /health HTTP/1.1" 200 OK
311
- INFO: 10.16.44.15:17594 - "GET /health HTTP/1.1" 200 OK
312
- INFO: 10.16.44.15:47427 - "GET /health HTTP/1.1" 200 OK
313
- INFO: 10.16.44.15:45559 - "GET /health HTTP/1.1" 200 OK
314
- INFO: 10.16.18.108:38784 - "GET /health HTTP/1.1" 200 OK
315
- INFO: 10.16.18.114:42809 - "GET /health HTTP/1.1" 200 OK
316
- INFO: 10.16.44.15:64823 - "GET /health HTTP/1.1" 200 OK
317
- INFO: 10.16.8.187:51040 - "GET /health HTTP/1.1" 200 OK
318
- INFO: 10.16.18.108:42252 - "GET /health HTTP/1.1" 200 OK
319
- INFO: 10.16.18.114:31076 - "GET /health HTTP/1.1" 200 OK
320
- INFO: 10.16.18.108:63922 - "GET /health HTTP/1.1" 200 OK
321
- INFO: 10.16.8.187:64385 - "GET /health HTTP/1.1" 200 OK
322
- INFO: 10.16.44.15:34470 - "GET /health HTTP/1.1" 200 OK
323
- INFO: 10.16.18.108:61501 - "GET /health HTTP/1.1" 200 OK
324
- INFO: 10.16.44.15:53570 - "GET /health HTTP/1.1" 200 OK
325
- INFO: 10.16.44.15:33492 - "GET /health HTTP/1.1" 200 OK
326
- INFO: 10.16.44.15:43966 - "GET /health HTTP/1.1" 200 OK
327
- INFO: 10.16.18.108:4258 - "GET /health HTTP/1.1" 200 OK
328
- INFO: 10.16.44.15:1597 - "GET /health HTTP/1.1" 200 OK
329
- INFO: 10.16.44.15:56793 - "GET /health HTTP/1.1" 200 OK
330
- INFO: 10.16.18.108:21357 - "GET /health HTTP/1.1" 200 OK
331
- INFO: 10.16.18.108:11635 - "GET /health HTTP/1.1" 200 OK
332
- INFO: 10.16.18.114:18653 - "GET /health HTTP/1.1" 200 OK
333
- INFO: 10.16.18.108:5353 - "GET /health HTTP/1.1" 200 OK
334
- INFO: 10.16.44.15:20537 - "GET /health HTTP/1.1" 200 OK
335
- INFO: 10.16.44.15:2247 - "GET /health HTTP/1.1" 200 OK
336
- INFO: 10.16.18.108:23219 - "GET /health HTTP/1.1" 200 OK
337
- INFO: 10.16.18.114:47975 - "GET /health HTTP/1.1" 200 OK
338
- INFO: 10.16.8.187:1679 - "GET /health HTTP/1.1" 200 OK
339
- INFO: 10.16.8.187:49086 - "GET /health HTTP/1.1" 200 OK
340
- INFO: 10.16.18.108:31122 - "GET /health HTTP/1.1" 200 OK
341
- INFO: 10.16.8.187:63659 - "GET /health HTTP/1.1" 200 OK
342
- INFO: 10.16.18.108:27057 - "GET /health HTTP/1.1" 200 OK
343
- INFO: 10.16.18.114:1366 - "GET /health HTTP/1.1" 200 OK
344
- INFO: 10.16.44.15:47745 - "GET /health HTTP/1.1" 200 OK
345
- INFO: 10.16.18.114:51128 - "GET /health HTTP/1.1" 200 OK
346
- INFO: 10.16.18.114:25028 - "GET /health HTTP/1.1" 200 OK
347
- INFO: 10.16.44.15:33322 - "GET /health HTTP/1.1" 200 OK
348
- INFO: 10.16.18.108:22827 - "GET /health HTTP/1.1" 200 OK
349
- INFO: 10.16.18.108:37362 - "GET /health HTTP/1.1" 200 OK
350
- INFO: 10.16.44.15:7570 - "GET /health HTTP/1.1" 200 OK
351
- INFO: 10.16.44.15:25355 - "GET /health HTTP/1.1" 200 OK
352
- INFO: 10.16.18.114:28388 - "GET /health HTTP/1.1" 200 OK
353
- INFO: 10.16.44.15:58608 - "GET /health HTTP/1.1" 200 OK
354
- INFO: 10.16.44.15:39621 - "GET /health HTTP/1.1" 200 OK
355
- INFO: 10.16.44.15:44697 - "GET /health HTTP/1.1" 200 OK
356
- INFO: 10.16.44.15:39476 - "GET /health HTTP/1.1" 200 OK
357
- INFO: 10.16.44.15:64238 - "GET /health HTTP/1.1" 200 OK
358
- INFO: 10.16.8.187:23569 - "GET /health HTTP/1.1" 200 OK
359
- INFO: 10.16.8.187:19431 - "GET /health HTTP/1.1" 200 OK
360
- INFO: 10.16.44.15:31341 - "GET /health HTTP/1.1" 200 OK
361
- INFO: 10.16.18.108:7216 - "GET /health HTTP/1.1" 200 OK
362
- INFO: 10.16.8.187:19603 - "GET /health HTTP/1.1" 200 OK
363
- INFO: 10.16.44.15:35984 - "GET /health HTTP/1.1" 200 OK
364
- INFO: 2025-11-23T09:58:47 - app.core.supabase_auth: Session refreshed successfully
365
- INFO: 2025-11-23T09:58:47 - app.api.v1.auth: ✅ Token refreshed successfully for: nadina73@nembors.com
366
- INFO: 10.16.8.187:29807 - "POST /api/v1/auth/refresh-token HTTP/1.1" 200 OK
367
- INFO: 10.16.44.15:57864 - "GET /health HTTP/1.1" 200 OK
368
- INFO: 10.16.44.15:62779 - "GET /health HTTP/1.1" 200 OK
369
- INFO: 10.16.8.187:13903 - "GET /health HTTP/1.1" 200 OK
370
- INFO: 10.16.18.108:1313 - "GET /health HTTP/1.1" 200 OK
371
- INFO: 10.16.18.114:39450 - "GET /health HTTP/1.1" 200 OK
372
- INFO: 10.16.18.114:60754 - "GET /health HTTP/1.1" 200 OK
373
- INFO: 10.16.18.114:56234 - "GET /health HTTP/1.1" 200 OK
374
- INFO: 10.16.44.15:2064 - "GET /health HTTP/1.1" 200 OK
375
- INFO: 10.16.8.187:46202 - "GET /health HTTP/1.1" 200 OK
376
- INFO: 10.16.8.187:47739 - "GET /health HTTP/1.1" 200 OK
377
- INFO: 10.16.18.108:43242 - "GET /health HTTP/1.1" 200 OK
378
- INFO: 10.16.8.187:6390 - "GET /health HTTP/1.1" 200 OK
379
- INFO: 10.16.8.187:13927 - "GET /health HTTP/1.1" 200 OK
380
- INFO: 10.16.44.15:49290 - "GET /health HTTP/1.1" 200 OK
381
- INFO: 10.16.44.15:47876 - "GET /health HTTP/1.1" 200 OK
382
- INFO: 10.16.8.187:41317 - "GET /health HTTP/1.1" 200 OK
383
- INFO: 10.16.18.108:20371 - "GET /health HTTP/1.1" 200 OK
384
- INFO: 10.16.18.114:18273 - "GET /health HTTP/1.1" 200 OK
385
- INFO: 10.16.8.187:33907 - "GET /health HTTP/1.1" 200 OK
386
- INFO: 10.16.44.15:47545 - "GET /health HTTP/1.1" 200 OK
387
- INFO: 10.16.18.108:6508 - "GET /health HTTP/1.1" 200 OK
388
- INFO: 10.16.44.15:2833 - "GET /health HTTP/1.1" 200 OK
389
- INFO: 10.16.18.114:9118 - "GET /health HTTP/1.1" 200 OK
390
- INFO: 10.16.44.15:42209 - "GET /health HTTP/1.1" 200 OK
391
- INFO: 10.16.18.108:34868 - "GET /health HTTP/1.1" 200 OK
392
- INFO: 10.16.18.108:23098 - "GET /health HTTP/1.1" 200 OK
393
- INFO: 10.16.8.187:48209 - "GET /health HTTP/1.1" 200 OK
394
- INFO: 10.16.44.15:27932 - "GET /health HTTP/1.1" 200 OK
395
- INFO: 10.16.8.187:6776 - "GET /health HTTP/1.1" 200 OK
396
- INFO: 10.16.18.108:14991 - "GET /health HTTP/1.1" 200 OK
397
- INFO: 10.16.18.108:14217 - "GET /health HTTP/1.1" 200 OK
398
- INFO: 10.16.8.187:5497 - "GET /health HTTP/1.1" 200 OK
399
- INFO: 10.16.44.15:10409 - "GET /health HTTP/1.1" 200 OK
400
- INFO: 10.16.18.114:27257 - "GET /health HTTP/1.1" 200 OK
401
- INFO: 10.16.8.187:45763 - "GET /health HTTP/1.1" 200 OK
402
- INFO: 10.16.18.108:2819 - "GET /health HTTP/1.1" 200 OK
403
- INFO: 10.16.18.114:28298 - "GET /health HTTP/1.1" 200 OK
404
- INFO: 10.16.18.114:9778 - "GET /health HTTP/1.1" 200 OK
405
- INFO: 10.16.44.15:63469 - "GET /health HTTP/1.1" 200 OK
406
- INFO: 10.16.18.108:41691 - "GET /health HTTP/1.1" 200 OK
407
- INFO: 10.16.8.187:56559 - "GET /health HTTP/1.1" 200 OK
408
- INFO: 10.16.18.108:2513 - "GET /health HTTP/1.1" 200 OK
409
- INFO: 10.16.8.187:56380 - "GET /health HTTP/1.1" 200 OK
410
- INFO: 10.16.8.187:60249 - "GET /health HTTP/1.1" 200 OK
411
- INFO: 10.16.44.15:22052 - "GET /health HTTP/1.1" 200 OK
412
- INFO: 10.16.44.15:22587 - "GET /health HTTP/1.1" 200 OK
413
- INFO: 10.16.18.108:24991 - "GET /health HTTP/1.1" 200 OK
414
- INFO: 10.16.18.114:10788 - "GET /health HTTP/1.1" 200 OK
415
- INFO: 10.16.44.15:63942 - "GET /health HTTP/1.1" 200 OK
416
- INFO: 10.16.44.15:19846 - "GET /health HTTP/1.1" 200 OK
417
- INFO: 10.16.18.114:23034 - "GET /health HTTP/1.1" 200 OK
418
- INFO: 10.16.44.15:1435 - "GET /health HTTP/1.1" 200 OK
419
- INFO: 10.16.18.114:57809 - "GET /health HTTP/1.1" 200 OK
420
- INFO: 10.16.18.114:59458 - "GET /health HTTP/1.1" 200 OK
421
- INFO: 2025-11-23T10:53:48 - app.core.supabase_auth: Session refreshed successfully
422
- INFO: 2025-11-23T10:53:48 - app.api.v1.auth: ✅ Token refreshed successfully for: nadina73@nembors.com
423
- INFO: 10.16.18.108:21771 - "POST /api/v1/auth/refresh-token HTTP/1.1" 200 OK
424
- INFO: 10.16.18.108:28552 - "GET /health HTTP/1.1" 200 OK
425
- INFO: 10.16.8.187:64221 - "GET /health HTTP/1.1" 200 OK
426
- INFO: 10.16.18.108:28423 - "GET /health HTTP/1.1" 200 OK
427
- INFO: 10.16.18.108:3596 - "GET /health HTTP/1.1" 200 OK
428
- INFO: 10.16.8.187:3516 - "GET /health HTTP/1.1" 200 OK
429
- INFO: 10.16.8.187:37677 - "GET /health HTTP/1.1" 200 OK
430
- INFO: 10.16.8.187:28724 - "GET /health HTTP/1.1" 200 OK
431
- INFO: 10.16.18.114:7174 - "GET /health HTTP/1.1" 200 OK
432
- INFO: 10.16.18.114:10375 - "GET /health HTTP/1.1" 200 OK
433
- INFO: 10.16.18.108:27331 - "GET /health HTTP/1.1" 200 OK
434
- INFO: 10.16.8.187:49170 - "GET /health HTTP/1.1" 200 OK
435
- INFO: 10.16.8.187:64193 - "GET /health HTTP/1.1" 200 OK
436
- INFO: 10.16.18.108:1126 - "GET /health HTTP/1.1" 200 OK
437
- INFO: 10.16.44.15:1132 - "GET /health HTTP/1.1" 200 OK
438
- INFO: 10.16.18.114:34263 - "GET /health HTTP/1.1" 200 OK
439
- INFO: 10.16.18.114:55295 - "GET /health HTTP/1.1" 200 OK
440
- INFO: 10.16.18.114:4500 - "GET /health HTTP/1.1" 200 OK
441
- INFO: 10.16.44.15:49177 - "GET /health HTTP/1.1" 200 OK
442
- INFO: 10.16.18.108:8240 - "GET /health HTTP/1.1" 200 OK
443
- INFO: 10.16.18.108:63815 - "GET /health HTTP/1.1" 200 OK
444
- INFO: 10.16.18.108:32709 - "GET /health HTTP/1.1" 200 OK
445
- INFO: 10.16.18.114:61194 - "GET /health HTTP/1.1" 200 OK
446
- INFO: 10.16.18.114:41077 - "GET /health HTTP/1.1" 200 OK
447
- INFO: 10.16.18.114:10638 - "GET /health HTTP/1.1" 200 OK
448
- INFO: 10.16.18.114:24766 - "GET /health HTTP/1.1" 200 OK
449
- INFO: 10.16.18.114:22528 - "GET /health HTTP/1.1" 200 OK
450
- INFO: 10.16.18.114:54847 - "GET /health HTTP/1.1" 200 OK
451
- INFO: 10.16.18.114:63943 - "GET /health HTTP/1.1" 200 OK
452
- INFO: 10.16.18.114:52806 - "GET /health HTTP/1.1" 200 OK
453
- INFO: 10.16.44.15:25630 - "GET /health HTTP/1.1" 200 OK
454
- INFO: 10.16.8.187:44661 - "GET /health HTTP/1.1" 200 OK
455
- INFO: 10.16.44.15:56085 - "GET /health HTTP/1.1" 200 OK
456
- INFO: 10.16.8.187:1569 - "GET /health HTTP/1.1" 200 OK
457
- INFO: 10.16.18.114:3942 - "GET /health HTTP/1.1" 200 OK
458
- INFO: 10.16.18.108:64117 - "GET /health HTTP/1.1" 200 OK
459
- INFO: 10.16.18.114:53230 - "GET /health HTTP/1.1" 200 OK
460
- INFO: 10.16.18.114:62228 - "GET /health HTTP/1.1" 200 OK
461
- INFO: 10.16.8.187:38213 - "GET /health HTTP/1.1" 200 OK
462
- INFO: 10.16.44.15:22910 - "GET /health HTTP/1.1" 200 OK
463
- INFO: 10.16.18.114:46081 - "GET /health HTTP/1.1" 200 OK
464
- INFO: 10.16.8.187:40260 - "GET /health HTTP/1.1" 200 OK
465
- INFO: 10.16.44.15:30895 - "GET /health HTTP/1.1" 200 OK
466
- INFO: 10.16.44.15:63480 - "GET /health HTTP/1.1" 200 OK
467
- INFO: 10.16.8.187:59591 - "GET /health HTTP/1.1" 200 OK
468
- INFO: 10.16.8.187:4221 - "GET /health HTTP/1.1" 200 OK
469
- INFO: 10.16.8.187:22412 - "GET /health HTTP/1.1" 200 OK
470
- INFO: 10.16.18.108:60243 - "GET /health HTTP/1.1" 200 OK
471
- INFO: 10.16.18.114:63064 - "GET /health HTTP/1.1" 200 OK
472
- INFO: 10.16.8.187:29655 - "GET /health HTTP/1.1" 200 OK
473
- INFO: 10.16.18.114:55296 - "GET /health HTTP/1.1" 200 OK
474
- INFO: 10.16.18.108:40881 - "GET /health HTTP/1.1" 200 OK
475
- INFO: 10.16.8.187:27435 - "GET /health HTTP/1.1" 200 OK
476
- INFO: 10.16.18.114:50078 - "GET /health HTTP/1.1" 200 OK
477
- INFO: 10.16.44.15:46862 - "GET /health HTTP/1.1" 200 OK
478
- INFO: 10.16.44.15:35144 - "GET /health HTTP/1.1" 200 OK
479
- INFO: 10.16.8.187:6583 - "GET /health HTTP/1.1" 200 OK
480
- INFO: 10.16.18.114:20853 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
481
- INFO: 10.16.18.114:20853 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a HTTP/1.1" 200 OK
482
- INFO: 10.16.8.187:6583 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions HTTP/1.1" 200 OK
483
- INFO: 10.16.8.187:31781 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/project-roles HTTP/1.1" 200 OK
484
- INFO: 10.16.8.187:16010 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
485
- INFO: 10.16.18.114:3807 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
486
- INFO: 10.16.18.114:42643 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/subcontractors HTTP/1.1" 200 OK
487
- INFO: 2025-11-23T11:48:50 - app.core.supabase_auth: Session refreshed successfully
488
- INFO: 2025-11-23T11:48:50 - app.api.v1.auth: ✅ Token refreshed successfully for: nadina73@nembors.com
489
- INFO: 10.16.18.108:16173 - "POST /api/v1/auth/refresh-token HTTP/1.1" 200 OK
490
- INFO: 10.16.18.108:16173 - "GET /health HTTP/1.1" 200 OK
491
- INFO: 10.16.8.187:59361 - "GET /api/v1/users?skip=0&limit=100 HTTP/1.1" 200 OK
492
- INFO: 10.16.18.114:27761 - "GET /health HTTP/1.1" 200 OK
493
- INFO: 10.16.18.108:47984 - "GET /health HTTP/1.1" 200 OK
494
- INFO: 10.16.18.108:12596 - "GET /health HTTP/1.1" 200 OK
495
- INFO: 10.16.18.114:32055 - "GET /health HTTP/1.1" 200 OK
496
- ERROR: 2025-11-23T11:52:18 - app.api.v1.projects: Error creating region: 'ProjectRegionCreate' object has no attribute 'is_active'
497
- INFO: 10.16.8.187:10990 - "POST /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions HTTP/1.1" 500 Internal Server Error
 
1
+ ===== Application Startup at 2025-11-23 12:02:50 =====
2
 
3
  INFO: Started server process [7]
4
  INFO: Waiting for application startup.
5
+ INFO: 2025-11-23T12:03:10 - app.main: ============================================================
6
+ INFO: 2025-11-23T12:03:10 - app.main: 🚀 SwiftOps API v1.0.0 | PRODUCTION
7
+ INFO: 2025-11-23T12:03:10 - app.main: ============================================================
8
+ INFO: 2025-11-23T12:03:10 - app.main: 📦 Database:
9
+ INFO: 2025-11-23T12:03:10 - app.main: ✓ Connected | 44 tables | 5 users
10
+ INFO: 2025-11-23T12:03:10 - app.main: 💾 Cache & Sessions:
11
+ INFO: 2025-11-23T12:03:11 - app.services.otp_service: ✅ OTP Service initialized with Redis storage
12
+ INFO: 2025-11-23T12:03:11 - app.main: ✓ Redis: Connected
13
+ INFO: 2025-11-23T12:03:11 - app.main: 🔌 External Services:
 
 
 
 
 
 
 
14
  INFO: Application startup complete.
15
+ INFO: 2025-11-23T12:03:12 - app.main: ✓ Cloudinary: Connected
16
+ INFO: 2025-11-23T12:03:12 - app.main: ✓ Resend: Configured
17
+ INFO: 2025-11-23T12:03:12 - app.main: ✓ WASender: Connected
18
+ INFO: 2025-11-23T12:03:12 - app.main: ✓ Supabase: Connected | 6 buckets
19
+ INFO: 2025-11-23T12:03:12 - app.main: ============================================================
20
+ INFO: 2025-11-23T12:03:12 - app.main: ✅ Startup complete | Ready to serve requests
21
+ INFO: 2025-11-23T12:03:12 - app.main: ============================================================
22
  INFO: Uvicorn running on http://0.0.0.0:7860 (Press CTRL+C to quit)
23
+ INFO: 10.16.44.15:35125 - "GET /health HTTP/1.1" 200 OK
24
+ INFO: 10.16.44.15:2145 - "GET /health HTTP/1.1" 200 OK
25
+ INFO: 10.16.8.187:3401 - "GET /health HTTP/1.1" 200 OK
26
+ INFO: 10.16.44.15:8007 - "GET /health HTTP/1.1" 200 OK
27
+ INFO: 10.16.18.114:36498 - "GET /health HTTP/1.1" 200 OK
28
+ INFO: 2025-11-23T12:05:22 - app.services.project_service: Created region 'Test' for project 0ade6bd1-e492-4e25-b681-59f42058d29a
29
+ INFO: 2025-11-23T12:05:22 - app.services.audit_service: Audit log created: create on project_region by nadina73@nembors.com
30
+ INFO: 10.16.18.108:64355 - "POST /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions HTTP/1.1" 201 Created
31
+ INFO: 10.16.8.187:38463 - "GET /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions HTTP/1.1" 200 OK
32
+ INFO: 10.16.18.108:49587 - "GET /health HTTP/1.1" 200 OK
33
+ INFO: 10.16.18.114:27376 - "GET /health HTTP/1.1" 200 OK
34
+ INFO: 10.16.44.15:6176 - "GET / HTTP/1.1" 200 OK
35
+ INFO: 2025-11-23T12:06:29 - app.services.project_service: Updated region 4cd27765-5720-4cc0-872e-bf0da3cd1898
36
+ ERROR: 2025-11-23T12:06:29 - app.services.audit_service: Failed to create audit log: (builtins.TypeError) Object of type Decimal is not JSON serializable
37
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
38
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]]
39
+ ERROR: 2025-11-23T12:06:29 - app.api.v1.projects: Error updating region: 20 validation errors for ProjectRegionResponse
40
+ region_name
41
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
42
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
43
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
44
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
45
+ region_code
46
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
47
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
48
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
49
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
50
+ description
51
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
52
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
53
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
54
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
55
+ country
56
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
57
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
58
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
59
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
60
+ region
61
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
62
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
63
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
64
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
65
+ city
66
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
67
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
68
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
69
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
70
+ address_line1
71
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
72
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
73
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
74
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
75
+ address_line2
76
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
77
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
78
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
79
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
80
+ maps_link
81
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
82
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
83
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
84
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
85
+ latitude
86
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
87
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
88
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
89
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
90
+ longitude
91
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
92
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
93
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
94
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
95
+ notes
96
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
97
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
98
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
99
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
100
+ id
101
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
102
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
103
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
104
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
105
+ project_id
106
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
107
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
108
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
109
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
110
+ manager_id
111
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
112
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
113
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
114
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
115
+ is_active
116
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
117
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
118
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
119
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
120
+ hub_contact_persons
121
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
122
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
123
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
124
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
125
+ additional_metadata
126
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
127
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
128
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
129
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
130
+ created_at
131
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
132
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
133
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
134
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
135
+ updated_at
136
+ Error extracting attribute: PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (builtins.TypeError) Object of type Decimal is not JSON serializable
137
+ [SQL: INSERT INTO audit_logs (id, user_id, user_email, user_role, action, entity_type, entity_id, description, changes, ip_address, user_agent, request_id, latitude, longitude, additional_metadata, created_at) VALUES (%(id)s::UUID, %(user_id)s::UUID, %(user_email)s, %(user_role)s, %(action)s, %(entity_type)s, %(entity_id)s::UUID, %(description)s, %(changes)s, %(ip_address)s, %(user_agent)s, %(request_id)s, %(latitude)s, %(longitude)s, %(additional_metadata)s, %(created_at)s)]
138
+ [parameters: [{'user_id': UUID('c5cf92be-4172-4fe2-af5c-f05d83b3a938'), 'ip_address': '10.16.18.108', 'changes': {'region_name': 'Test', 'region_code': 'testa', 'de ... (701 characters truncated) ... {}, 'action': 'update', 'user_email': 'nadina73@nembors.com', 'user_role': 'project_manager', 'latitude': None, 'request_id': None, 'longitude': None}]] (Background on this error at: https://sqlalche.me/e/20/7s2a) [type=get_attribute_error, input_value=<unprintable ProjectRegion object>, input_type=ProjectRegion]
139
+ For further information visit https://errors.pydantic.dev/2.5/v/get_attribute_error
140
+ INFO: 10.16.18.108:50773 - "PATCH /api/v1/projects/0ade6bd1-e492-4e25-b681-59f42058d29a/regions/4cd27765-5720-4cc0-872e-bf0da3cd1898 HTTP/1.1" 500 Internal Server Error
141
+ INFO: 10.16.8.187:33284 - "GET /health HTTP/1.1" 200 OK
142
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/app/services/audit_service.py CHANGED
@@ -2,6 +2,9 @@
2
  Audit Service - Centralized audit logging
3
  """
4
  import logging
 
 
 
5
  from typing import Optional, Dict, Any
6
  from sqlalchemy.orm import Session
7
  from fastapi import Request
@@ -12,6 +15,26 @@ from app.models.user import User
12
  logger = logging.getLogger(__name__)
13
 
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  class AuditService:
16
  """Service for logging user actions to audit trail"""
17
 
@@ -58,6 +81,10 @@ class AuditService:
58
  # Get user agent
59
  user_agent = request.headers.get("user-agent")
60
 
 
 
 
 
61
  # Create audit log entry
62
  audit_log = AuditLog(
63
  user_id=user.id if user else None,
@@ -67,10 +94,10 @@ class AuditService:
67
  entity_type=entity_type,
68
  entity_id=entity_id,
69
  description=description,
70
- changes=changes or {},
71
  ip_address=ip_address,
72
  user_agent=user_agent,
73
- additional_metadata=additional_metadata or {}
74
  )
75
 
76
  db.add(audit_log)
@@ -84,8 +111,9 @@ class AuditService:
84
 
85
  except Exception as e:
86
  logger.error(f"Failed to create audit log: {str(e)}")
 
 
87
  # Don't fail the main operation if audit logging fails
88
- # Note: No rollback here - let parent transaction handle it
89
  return None
90
 
91
  @staticmethod
 
2
  Audit Service - Centralized audit logging
3
  """
4
  import logging
5
+ import json
6
+ from decimal import Decimal
7
+ from datetime import datetime, date
8
  from typing import Optional, Dict, Any
9
  from sqlalchemy.orm import Session
10
  from fastapi import Request
 
15
  logger = logging.getLogger(__name__)
16
 
17
 
18
+ def _serialize_for_json(obj: Any) -> Any:
19
+ """
20
+ Convert non-JSON-serializable types to JSON-compatible types
21
+
22
+ Handles:
23
+ - Decimal -> float
24
+ - datetime/date -> ISO string
25
+ - Other objects -> string representation
26
+ """
27
+ if isinstance(obj, Decimal):
28
+ return float(obj)
29
+ elif isinstance(obj, (datetime, date)):
30
+ return obj.isoformat()
31
+ elif isinstance(obj, dict):
32
+ return {k: _serialize_for_json(v) for k, v in obj.items()}
33
+ elif isinstance(obj, (list, tuple)):
34
+ return [_serialize_for_json(item) for item in obj]
35
+ return obj
36
+
37
+
38
  class AuditService:
39
  """Service for logging user actions to audit trail"""
40
 
 
81
  # Get user agent
82
  user_agent = request.headers.get("user-agent")
83
 
84
+ # Sanitize changes and metadata for JSON serialization
85
+ sanitized_changes = _serialize_for_json(changes or {})
86
+ sanitized_metadata = _serialize_for_json(additional_metadata or {})
87
+
88
  # Create audit log entry
89
  audit_log = AuditLog(
90
  user_id=user.id if user else None,
 
94
  entity_type=entity_type,
95
  entity_id=entity_id,
96
  description=description,
97
+ changes=sanitized_changes,
98
  ip_address=ip_address,
99
  user_agent=user_agent,
100
+ additional_metadata=sanitized_metadata
101
  )
102
 
103
  db.add(audit_log)
 
111
 
112
  except Exception as e:
113
  logger.error(f"Failed to create audit log: {str(e)}")
114
+ # Rollback this audit log attempt to prevent session corruption
115
+ db.rollback()
116
  # Don't fail the main operation if audit logging fails
 
117
  return None
118
 
119
  @staticmethod
src/app/services/project_service.py CHANGED
@@ -777,29 +777,84 @@ class ProjectService:
777
  current_user: User
778
  ) -> ProjectRegion:
779
  """
780
- Create a new project region/hub
781
 
782
  Authorization:
783
  - platform_admin: Can create for any project
784
  - project_manager: Can create for their own projects
 
 
 
 
785
  """
786
  # Get and validate project
787
  project = ProjectService._get_project_with_auth(db, project_id, current_user)
788
 
789
- # Check for duplicate region name in this project
790
- existing = db.query(ProjectRegion).filter(
791
- ProjectRegion.project_id == project_id,
792
- ProjectRegion.region_name == data.region_name,
793
- ProjectRegion.deleted_at == None
794
- ).first()
 
 
795
 
 
 
 
 
 
 
 
 
796
  if existing:
797
- raise HTTPException(
798
- status_code=status.HTTP_400_BAD_REQUEST,
799
- detail=f"Region '{data.region_name}' already exists in this project"
800
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
801
 
802
- # Validate manager if provided
803
  if data.manager_id:
804
  manager = db.query(User).filter(
805
  User.id == data.manager_id,
@@ -989,31 +1044,48 @@ class ProjectService:
989
  current_user: User
990
  ) -> ProjectRole:
991
  """
992
- Create a new project role with compensation structure
993
 
994
  Authorization:
995
  - platform_admin: Can create for any project
996
  - project_manager: Can create for their own projects
 
 
 
 
997
  """
998
  # Get and validate project
999
  project = ProjectService._get_project_with_auth(db, project_id, current_user)
1000
 
1001
- # Check for duplicate role name in this project
1002
  existing = db.query(ProjectRole).filter(
1003
  ProjectRole.project_id == project_id,
1004
  ProjectRole.role_name == data.role_name,
1005
  ProjectRole.deleted_at == None
1006
  ).first()
1007
 
1008
- if existing:
1009
- raise HTTPException(
1010
- status_code=status.HTTP_400_BAD_REQUEST,
1011
- detail=f"Role '{data.role_name}' already exists in this project"
1012
- )
1013
-
1014
  # Validate compensation type and required fields
1015
  ProjectService._validate_compensation_structure(data)
1016
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1017
  # Create role
1018
  role = ProjectRole(
1019
  project_id=project_id,
@@ -1205,11 +1277,15 @@ class ProjectService:
1205
  current_user: User
1206
  ) -> ProjectSubcontractor:
1207
  """
1208
- Add a subcontractor to a project
1209
 
1210
  Authorization:
1211
  - platform_admin: Can add to any project
1212
  - project_manager: Can add to their own projects
 
 
 
 
1213
  """
1214
  # Get and validate project
1215
  project = ProjectService._get_project_with_auth(db, project_id, current_user)
@@ -1253,7 +1329,7 @@ class ProjectService:
1253
  detail=f"Region {data.project_region_id} not found in this project"
1254
  )
1255
 
1256
- # Check for duplicate (same subcontractor + region combination)
1257
  existing = db.query(ProjectSubcontractor).filter(
1258
  ProjectSubcontractor.project_id == project_id,
1259
  ProjectSubcontractor.subcontractor_id == data.subcontractor_id,
@@ -1262,12 +1338,24 @@ class ProjectService:
1262
  ).first()
1263
 
1264
  if existing:
1265
- raise HTTPException(
1266
- status_code=status.HTTP_400_BAD_REQUEST,
1267
- detail="This subcontractor is already assigned to this region"
1268
- )
 
 
 
 
 
 
 
 
 
 
 
 
1269
 
1270
- # Create subcontractor relationship
1271
  project_subcon = ProjectSubcontractor(
1272
  project_id=project_id,
1273
  subcontractor_id=data.subcontractor_id,
 
777
  current_user: User
778
  ) -> ProjectRegion:
779
  """
780
+ Create a new project region/hub (idempotent)
781
 
782
  Authorization:
783
  - platform_admin: Can create for any project
784
  - project_manager: Can create for their own projects
785
+
786
+ Idempotency:
787
+ - If region with same region_name OR region_code exists, updates it
788
+ - This allows frontend to safely re-save without errors
789
  """
790
  # Get and validate project
791
  project = ProjectService._get_project_with_auth(db, project_id, current_user)
792
 
793
+ # Check for existing region by name OR code (idempotency check)
794
+ existing = None
795
+ if data.region_name:
796
+ existing = db.query(ProjectRegion).filter(
797
+ ProjectRegion.project_id == project_id,
798
+ ProjectRegion.region_name == data.region_name,
799
+ ProjectRegion.deleted_at == None
800
+ ).first()
801
 
802
+ if not existing and data.region_code:
803
+ existing = db.query(ProjectRegion).filter(
804
+ ProjectRegion.project_id == project_id,
805
+ ProjectRegion.region_code == data.region_code,
806
+ ProjectRegion.deleted_at == None
807
+ ).first()
808
+
809
+ # If exists, update instead of creating (idempotent behavior)
810
  if existing:
811
+ logger.info(f"Region '{data.region_name}' already exists, updating instead")
812
+
813
+ # Validate manager if provided
814
+ if data.manager_id:
815
+ manager = db.query(User).filter(
816
+ User.id == data.manager_id,
817
+ User.deleted_at == None
818
+ ).first()
819
+
820
+ if not manager:
821
+ raise HTTPException(
822
+ status_code=status.HTTP_404_NOT_FOUND,
823
+ detail=f"Manager user {data.manager_id} not found"
824
+ )
825
+
826
+ # Convert hub_contact_persons to dict for JSONB storage
827
+ hub_contacts = None
828
+ if data.hub_contact_persons is not None:
829
+ hub_contacts = [
830
+ contact.model_dump() if hasattr(contact, 'model_dump') else contact
831
+ for contact in data.hub_contact_persons
832
+ ]
833
+
834
+ # Update all fields from data
835
+ existing.region_name = data.region_name
836
+ existing.region_code = data.region_code
837
+ existing.description = data.description
838
+ existing.country = data.country
839
+ existing.region = data.region
840
+ existing.city = data.city
841
+ existing.address_line1 = data.address_line1
842
+ existing.address_line2 = data.address_line2
843
+ existing.maps_link = data.maps_link
844
+ existing.latitude = data.latitude
845
+ existing.longitude = data.longitude
846
+ existing.manager_id = data.manager_id
847
+ existing.notes = data.notes
848
+ if hub_contacts is not None:
849
+ existing.hub_contact_persons = hub_contacts
850
+
851
+ db.commit()
852
+ db.refresh(existing)
853
+
854
+ logger.info(f"Updated existing region '{existing.region_name}' for project {project_id}")
855
+ return existing
856
 
857
+ # New region - validate and create
858
  if data.manager_id:
859
  manager = db.query(User).filter(
860
  User.id == data.manager_id,
 
1044
  current_user: User
1045
  ) -> ProjectRole:
1046
  """
1047
+ Create a new project role with compensation structure (idempotent)
1048
 
1049
  Authorization:
1050
  - platform_admin: Can create for any project
1051
  - project_manager: Can create for their own projects
1052
+
1053
+ Idempotency:
1054
+ - If role with same role_name exists, updates it
1055
+ - This allows frontend to safely re-save without errors
1056
  """
1057
  # Get and validate project
1058
  project = ProjectService._get_project_with_auth(db, project_id, current_user)
1059
 
1060
+ # Check for existing role by name (idempotency check)
1061
  existing = db.query(ProjectRole).filter(
1062
  ProjectRole.project_id == project_id,
1063
  ProjectRole.role_name == data.role_name,
1064
  ProjectRole.deleted_at == None
1065
  ).first()
1066
 
 
 
 
 
 
 
1067
  # Validate compensation type and required fields
1068
  ProjectService._validate_compensation_structure(data)
1069
 
1070
+ if existing:
1071
+ # Update existing role (idempotent behavior)
1072
+ logger.info(f"Role '{data.role_name}' already exists, updating instead")
1073
+
1074
+ existing.role_description = data.role_description
1075
+ existing.compensation_type = data.compensation_type
1076
+ existing.flat_rate_amount = data.flat_rate_amount
1077
+ existing.commission_percentage = data.commission_percentage
1078
+ existing.hourly_rate = data.hourly_rate
1079
+ existing.bonus_amount = data.bonus_amount
1080
+ existing.custom_compensation_structure = data.custom_compensation_structure
1081
+ existing.notes = data.notes
1082
+
1083
+ db.commit()
1084
+ db.refresh(existing)
1085
+
1086
+ logger.info(f"Updated existing role '{existing.role_name}' for project {project_id}")
1087
+ return existing
1088
+
1089
  # Create role
1090
  role = ProjectRole(
1091
  project_id=project_id,
 
1277
  current_user: User
1278
  ) -> ProjectSubcontractor:
1279
  """
1280
+ Add a subcontractor to a project (idempotent)
1281
 
1282
  Authorization:
1283
  - platform_admin: Can add to any project
1284
  - project_manager: Can add to their own projects
1285
+
1286
+ Idempotency:
1287
+ - If same subcontractor + region combination exists, updates it
1288
+ - This allows frontend to safely re-save without errors
1289
  """
1290
  # Get and validate project
1291
  project = ProjectService._get_project_with_auth(db, project_id, current_user)
 
1329
  detail=f"Region {data.project_region_id} not found in this project"
1330
  )
1331
 
1332
+ # Check for existing (same subcontractor + region combination) - idempotency
1333
  existing = db.query(ProjectSubcontractor).filter(
1334
  ProjectSubcontractor.project_id == project_id,
1335
  ProjectSubcontractor.subcontractor_id == data.subcontractor_id,
 
1338
  ).first()
1339
 
1340
  if existing:
1341
+ # Update existing relationship (idempotent behavior)
1342
+ logger.info(f"Subcontractor {data.subcontractor_id} already assigned, updating instead")
1343
+
1344
+ existing.scope_description = data.scope_description
1345
+ existing.contract_start_date = data.contract_start_date
1346
+ existing.contract_end_date = data.contract_end_date
1347
+ existing.contract_value = data.contract_value
1348
+ existing.currency = data.currency or 'KES'
1349
+ existing.notes = data.notes
1350
+ existing.is_active = True
1351
+
1352
+ db.commit()
1353
+ db.refresh(existing)
1354
+
1355
+ logger.info(f"Updated existing subcontractor relationship for project {project_id}")
1356
+ return existing
1357
 
1358
+ # Create new subcontractor relationship
1359
  project_subcon = ProjectSubcontractor(
1360
  project_id=project_id,
1361
  subcontractor_id=data.subcontractor_id,