kamau1 commited on
Commit
44ca2cd
·
1 Parent(s): dad7dc2

fix: correct get_db imports and remove duplicate definition

Browse files
docs/api/dashboards/pm/PM_DASHBOARD_API_REFERENCE.md ADDED
@@ -0,0 +1,1054 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Project Manager Dashboard - API Reference
2
+
3
+ **Version:** 1.0
4
+ **Last Updated:** 2025-11-19
5
+ **Audience:** Frontend Development Team
6
+
7
+ ---
8
+
9
+ ## Overview
10
+
11
+ This document provides all API endpoints needed to build a comprehensive Project Manager (PM) dashboard. The PM role requires visibility across sales, operations, finance, and resources to orchestrate daily field service operations.
12
+
13
+ ### PM Core Responsibilities
14
+ - Convert sales orders to work tickets
15
+ - Assign tickets to field agents
16
+ - Approve expenses and manage finances
17
+ - Track inventory and resources
18
+ - Generate payroll and invoices
19
+ - Monitor team performance
20
+
21
+ ---
22
+
23
+ ## Dashboard Layout Structure
24
+
25
+ ### Recommended Sections
26
+
27
+ 1. **Today's Overview** - Key metrics at a glance
28
+ 2. **Financial Snapshot** - Cash position and pending payments
29
+ 3. **Quick Actions** - Common PM tasks
30
+ 4. **Pending Sales Orders** - Orders awaiting conversion
31
+ 5. **Active Tickets** - Work in progress
32
+ 6. **Pending Approvals** - Expenses, payroll, invoices
33
+ 7. **Inventory Status** - Stock levels and alerts
34
+ 8. **Map View** - Geographic visualization
35
+ 9. **Team Status** - Agent availability
36
+
37
+ ---
38
+
39
+ ## API Endpoints by Feature
40
+
41
+ ### 1. Dashboard Overview Statistics
42
+
43
+ #### Get Platform Dashboard Stats
44
+ ```
45
+ GET /api/v1/analytics/platform-admin/dashboard
46
+ Authorization: Bearer {token}
47
+ ```
48
+
49
+ **Response Fields:**
50
+ - `users` - User statistics (total, active, by role)
51
+ - `organizations` - Client and contractor counts
52
+ - `tickets` - Ticket counts by status and type
53
+ - `projects` - Project statistics
54
+ - `assignments` - Assignment statistics
55
+ - `recent_activity` - Latest 10 audit logs
56
+ - `system_health` - 30-day trends
57
+
58
+ **Use Case:** Main dashboard metrics widget
59
+
60
+ ---
61
+
62
+ ### 2. Sales Order Management
63
+
64
+ #### List Sales Orders
65
+ ```
66
+ GET /api/v1/sales-orders
67
+ Authorization: Bearer {token}
68
+
69
+ Query Parameters:
70
+ - skip (int, default: 0)
71
+ - limit (int, default: 50, max: 100)
72
+ - project_id (UUID, optional)
73
+ - status (string, optional) - "pending", "processed", "cancelled", "duplicate"
74
+ - project_region_id (UUID, optional)
75
+ - sales_agent_id (UUID, optional)
76
+ - from_date (date, optional)
77
+ - to_date (date, optional)
78
+ - pending_processing (boolean, optional) - Show only pending orders
79
+ - customer_phone (string, optional)
80
+ ```
81
+
82
+ **Response:**
83
+ - `items[]` - Array of sales orders with computed properties
84
+ - `total` - Total count
85
+ - `skip`, `limit` - Pagination info
86
+
87
+ **Key Fields per Item:**
88
+ - `id`, `order_number`, `customer_name`, `customer_preferred_package`
89
+ - `package_price`, `installation_address_line1`, `installation_latitude`, `installation_longitude`
90
+ - `status`, `project_title`, `region_name`, `sales_agent_name`
91
+ - `is_pending`, `has_ticket`, `can_promote_to_ticket`
92
+
93
+ #### Get Sales Order Statistics
94
+ ```
95
+ GET /api/v1/sales-orders/stats
96
+ Authorization: Bearer {token}
97
+
98
+ Query Parameters:
99
+ - project_id (UUID, optional)
100
+ - project_region_id (UUID, optional)
101
+ - sales_agent_id (UUID, optional)
102
+ ```
103
+
104
+ **Response:** Metrics on orders by status, region, agent
105
+
106
+ #### Assign Sales Order to Region
107
+ ```
108
+ POST /api/v1/sales-orders/{sales_order_id}/assign-region
109
+ Authorization: Bearer {token}
110
+ Content-Type: application/json
111
+
112
+ Body:
113
+ {
114
+ "project_region_id": "uuid"
115
+ }
116
+ ```
117
+
118
+ #### Promote Sales Order to Ticket (Single)
119
+ ```
120
+ POST /api/v1/sales-orders/{sales_order_id}/promote
121
+ Authorization: Bearer {token}
122
+ Content-Type: application/json
123
+
124
+ Body:
125
+ {
126
+ "priority": "normal",
127
+ "scheduled_date": "2025-01-20",
128
+ "scheduled_time_slot": "morning",
129
+ "work_description": "Install fiber",
130
+ "notes": "Customer prefers morning"
131
+ }
132
+ ```
133
+
134
+ **Response:**
135
+ - `message`, `sales_order_id`, `ticket_id`, `ticket_name`, `status`
136
+
137
+ #### Bulk Promote Sales Orders to Tickets
138
+ ```
139
+ POST /api/v1/sales-orders/bulk-promote
140
+ Authorization: Bearer {token}
141
+ Content-Type: application/json
142
+
143
+ Body:
144
+ {
145
+ "sales_order_ids": ["uuid1", "uuid2"],
146
+ "priority": "normal",
147
+ "notes": "Batch promotion"
148
+ }
149
+ ```
150
+
151
+ **Response:**
152
+ - `total`, `successful`, `failed`, `errors[]`, `created_ticket_ids[]`
153
+
154
+ ---
155
+
156
+ ### 3. Ticket Management
157
+
158
+ #### List Tickets
159
+ ```
160
+ GET /api/v1/tickets
161
+ Authorization: Bearer {token}
162
+
163
+ Query Parameters:
164
+ - skip (int, default: 0)
165
+ - limit (int, default: 50, max: 100)
166
+ - project_id (UUID, optional)
167
+ - status (enum, optional) - "open", "assigned", "in_progress", "pending_review", "completed", "cancelled"
168
+ - ticket_type (enum, optional) - "installation", "support", "infrastructure"
169
+ - priority (enum, optional) - "low", "normal", "high", "urgent"
170
+ - project_region_id (UUID, optional)
171
+ - source (enum, optional) - "sales_order", "incident", "task"
172
+ - from_date (date, optional)
173
+ - to_date (date, optional)
174
+ - is_overdue (boolean, optional)
175
+ ```
176
+
177
+ **Response:**
178
+ - `tickets[]` - Array of tickets
179
+ - `total`, `skip`, `limit`
180
+
181
+ **Key Fields per Ticket:**
182
+ - `id`, `ticket_name`, `status`, `priority`, `ticket_type`
183
+ - `work_description`, `scheduled_date`, `scheduled_time_slot`
184
+ - `project_title`, `region_name`, `customer_name`
185
+ - `is_overdue`, `can_be_assigned`
186
+
187
+ #### Get Ticket Statistics
188
+ ```
189
+ GET /api/v1/tickets/stats
190
+ Authorization: Bearer {token}
191
+
192
+ Query Parameters:
193
+ - project_id (UUID, optional)
194
+ - project_region_id (UUID, optional)
195
+ ```
196
+
197
+ **Response:**
198
+ - Counts by status, type, priority
199
+ - `overdue_tickets`, `avg_completion_time_hours`, `completion_rate`
200
+
201
+ #### Update Ticket
202
+ ```
203
+ PUT /api/v1/tickets/{ticket_id}
204
+ Authorization: Bearer {token}
205
+ Content-Type: application/json
206
+
207
+ Body:
208
+ {
209
+ "priority": "urgent",
210
+ "work_description": "Updated description",
211
+ "notes": "Additional notes"
212
+ }
213
+ ```
214
+
215
+ #### Reschedule Ticket
216
+ ```
217
+ POST /api/v1/tickets/{ticket_id}/reschedule
218
+ Authorization: Bearer {token}
219
+ Content-Type: application/json
220
+
221
+ Body:
222
+ {
223
+ "scheduled_date": "2025-01-25",
224
+ "scheduled_time_slot": "afternoon",
225
+ "reason": "Customer requested later date"
226
+ }
227
+ ```
228
+
229
+ #### Cancel Ticket
230
+ ```
231
+ POST /api/v1/tickets/{ticket_id}/cancel
232
+ Authorization: Bearer {token}
233
+ Content-Type: application/json
234
+
235
+ Body:
236
+ {
237
+ "reason": "Customer cancelled service"
238
+ }
239
+ ```
240
+
241
+ ---
242
+
243
+ ### 4. Ticket Assignment & Dispatch
244
+
245
+ #### List Ticket Assignments
246
+ ```
247
+ GET /api/v1/ticket-assignments
248
+ Authorization: Bearer {token}
249
+
250
+ Query Parameters:
251
+ - skip (int, default: 0)
252
+ - limit (int, default: 50)
253
+ - ticket_id (UUID, optional)
254
+ - user_id (UUID, optional)
255
+ - status (string, optional)
256
+ - project_id (UUID, optional)
257
+ - from_date (date, optional)
258
+ - to_date (date, optional)
259
+ ```
260
+
261
+ #### Get Available Agents for Assignment
262
+ ```
263
+ GET /api/v1/ticket-assignments/available-agents
264
+ Authorization: Bearer {token}
265
+
266
+ Query Parameters:
267
+ - ticket_id (UUID, required)
268
+ ```
269
+
270
+ **Response:** List of agents available to be assigned to the ticket
271
+
272
+ #### Assign Ticket to Agent
273
+ ```
274
+ POST /api/v1/ticket-assignments
275
+ Authorization: Bearer {token}
276
+ Content-Type: application/json
277
+
278
+ Body:
279
+ {
280
+ "ticket_id": "uuid",
281
+ "user_id": "uuid",
282
+ "notes": "Assigned to John"
283
+ }
284
+ ```
285
+
286
+ #### Reassign Ticket
287
+ ```
288
+ POST /api/v1/ticket-assignments/{assignment_id}/reassign
289
+ Authorization: Bearer {token}
290
+ Content-Type: application/json
291
+
292
+ Body:
293
+ {
294
+ "new_user_id": "uuid",
295
+ "reason": "Original agent unavailable"
296
+ }
297
+ ```
298
+
299
+ ---
300
+
301
+ ### 5. Expense Management
302
+
303
+ #### List Expenses
304
+ ```
305
+ GET /api/v1/expenses
306
+ Authorization: Bearer {token}
307
+
308
+ Query Parameters:
309
+ - page (int, default: 1)
310
+ - page_size (int, default: 50, max: 100)
311
+ - ticket_id (UUID, optional)
312
+ - assignment_id (UUID, optional)
313
+ - approval_status (string, optional) - "pending", "approved", "rejected"
314
+ - payment_status (string, optional) - "pending", "paid"
315
+ - from_date (date, optional)
316
+ - to_date (date, optional)
317
+ ```
318
+
319
+ **Response:**
320
+ - `items[]` - Array of expenses
321
+ - `total`, `page`, `page_size`
322
+
323
+ **Key Fields per Expense:**
324
+ - `id`, `expense_type`, `amount`, `currency`
325
+ - `description`, `receipt_url`
326
+ - `approval_status`, `payment_status`
327
+ - `submitted_by_name`, `approved_by_name`
328
+
329
+ #### Get Expense Statistics
330
+ ```
331
+ GET /api/v1/expenses/stats
332
+ Authorization: Bearer {token}
333
+
334
+ Query Parameters:
335
+ - ticket_id (UUID, optional)
336
+ - assignment_id (UUID, optional)
337
+ ```
338
+
339
+ **Response:** Total expenses, pending approvals, payment status breakdown
340
+
341
+ #### Approve/Reject Expense
342
+ ```
343
+ POST /api/v1/expenses/{expense_id}/approve
344
+ Authorization: Bearer {token}
345
+ Content-Type: application/json
346
+
347
+ Body:
348
+ {
349
+ "approved": true,
350
+ "notes": "Approved - receipt verified"
351
+ }
352
+ ```
353
+
354
+ #### Mark Expense as Paid
355
+ ```
356
+ POST /api/v1/expenses/{expense_id}/mark-paid
357
+ Authorization: Bearer {token}
358
+ Content-Type: application/json
359
+
360
+ Body:
361
+ {
362
+ "payment_date": "2025-01-20",
363
+ "payment_method": "mobile_money",
364
+ "payment_reference": "TXN123456",
365
+ "notes": "Paid via M-Pesa"
366
+ }
367
+ ```
368
+
369
+ ---
370
+
371
+ ### 6. Financial Management
372
+
373
+ #### List Financial Transactions
374
+ ```
375
+ GET /api/v1/finance
376
+ Authorization: Bearer {token}
377
+
378
+ Query Parameters:
379
+ - skip (int, default: 0)
380
+ - limit (int, default: 50, max: 100)
381
+ - project_id (UUID, optional)
382
+ - transaction_type (string, optional) - "inflow", "outflow"
383
+ - status (string, optional) - "pending", "approved", "paid", "rejected", "cancelled"
384
+ - category (string, optional)
385
+ - from_date (date, optional)
386
+ - to_date (date, optional)
387
+ - pending_approval (boolean, optional)
388
+ ```
389
+
390
+ #### Get Cash Flow Summary
391
+ ```
392
+ GET /api/v1/finance/cash-flow/{project_id}
393
+ Authorization: Bearer {token}
394
+
395
+ Query Parameters:
396
+ - from_date (date, optional)
397
+ - to_date (date, optional)
398
+ ```
399
+
400
+ **Response:**
401
+ - Total inflows, outflows, net cash flow
402
+ - Breakdown by category
403
+ - Pending transactions
404
+
405
+ #### Create Financial Transaction
406
+ ```
407
+ POST /api/v1/finance
408
+ Authorization: Bearer {token}
409
+ Content-Type: application/json
410
+
411
+ Body:
412
+ {
413
+ "project_id": "uuid",
414
+ "transaction_type": "outflow",
415
+ "amount": 50000,
416
+ "currency": "KES",
417
+ "category": "equipment_purchase",
418
+ "description": "Purchased 50 ONTs",
419
+ "transaction_date": "2025-01-20"
420
+ }
421
+ ```
422
+
423
+ #### Approve Transaction
424
+ ```
425
+ POST /api/v1/finance/{transaction_id}/approve
426
+ Authorization: Bearer {token}
427
+ Content-Type: application/json
428
+
429
+ Body:
430
+ {
431
+ "notes": "Approved by PM"
432
+ }
433
+ ```
434
+
435
+ ---
436
+
437
+ ### 7. Contractor Invoice Management
438
+
439
+ #### List Contractor Invoices
440
+ ```
441
+ GET /api/v1/invoices
442
+ Authorization: Bearer {token}
443
+
444
+ Query Parameters:
445
+ - skip (int, default: 0)
446
+ - limit (int, default: 100, max: 500)
447
+ - contractor_id (UUID, optional)
448
+ - client_id (UUID, optional)
449
+ - project_id (UUID, optional)
450
+ - status (string, optional) - "draft", "sent", "partially_paid", "paid", "cancelled"
451
+ - overdue_only (boolean, optional)
452
+ - unpaid_only (boolean, optional)
453
+ - latest_versions_only (boolean, default: true)
454
+ ```
455
+
456
+ **Response:**
457
+ - `invoices[]` - Array of invoices
458
+ - `total`, `skip`, `limit`
459
+
460
+ **Key Fields per Invoice:**
461
+ - `id`, `invoice_number`, `contractor_name`, `client_name`
462
+ - `subtotal_amount`, `tax_amount`, `total_amount`
463
+ - `amount_paid`, `amount_due`
464
+ - `status`, `due_date`, `is_overdue`
465
+
466
+ #### Create Contractor Invoice
467
+ ```
468
+ POST /api/v1/invoices
469
+ Authorization: Bearer {token}
470
+ Content-Type: application/json
471
+
472
+ Body:
473
+ {
474
+ "contractor_id": "uuid",
475
+ "client_id": "uuid",
476
+ "project_id": "uuid",
477
+ "invoice_date": "2025-01-20",
478
+ "due_date": "2025-02-20",
479
+ "currency": "KES",
480
+ "tax_rate": 16.0,
481
+ "notes": "Monthly invoice"
482
+ }
483
+ ```
484
+
485
+ **Response:** Created invoice with auto-generated invoice number
486
+
487
+ #### Add Line Item to Invoice
488
+ ```
489
+ POST /api/v1/invoices/{invoice_id}/line-items
490
+ Authorization: Bearer {token}
491
+ Content-Type: application/json
492
+
493
+ Body:
494
+ {
495
+ "line_item_type": "ticket",
496
+ "ticket_id": "uuid",
497
+ "description": "Installation service",
498
+ "quantity": 1,
499
+ "unit_price": 5000,
500
+ "amount": 5000
501
+ }
502
+ ```
503
+
504
+ **Note:** Creates new invoice version
505
+
506
+ #### Record Payment
507
+ ```
508
+ POST /api/v1/invoices/{invoice_id}/payments
509
+ Authorization: Bearer {token}
510
+ Content-Type: application/json
511
+
512
+ Body:
513
+ {
514
+ "amount": 50000,
515
+ "payment_date": "2025-01-20",
516
+ "payment_method": "bank_transfer",
517
+ "payment_reference": "TXN123456",
518
+ "notes": "Partial payment"
519
+ }
520
+ ```
521
+
522
+ **Response:** Updated invoice with new payment recorded
523
+
524
+ ---
525
+
526
+ ### 8. Inventory Management
527
+
528
+ #### List Main Office Inventory
529
+ ```
530
+ GET /api/v1/inventory
531
+ Authorization: Bearer {token}
532
+
533
+ Query Parameters:
534
+ - page (int, default: 1)
535
+ - page_size (int, default: 50, max: 100)
536
+ - project_id (UUID, optional)
537
+ - item_type (string, optional) - "tool", "equipment", "consumable", "ppe"
538
+ - status (string, optional)
539
+ - is_active (boolean, optional)
540
+ - search (string, optional)
541
+ ```
542
+
543
+ **Response:**
544
+ - `items[]` - Inventory batches
545
+ - `total`, `page`, `page_size`
546
+
547
+ **Key Fields per Item:**
548
+ - `id`, `equipment_type`, `equipment_name`, `item_type`
549
+ - `quantity_received`, `quantity_available`, `quantity_distributed`
550
+ - `status`, `received_date`
551
+
552
+ #### Create Inventory Batch
553
+ ```
554
+ POST /api/v1/inventory
555
+ Authorization: Bearer {token}
556
+ Content-Type: application/json
557
+
558
+ Body:
559
+ {
560
+ "project_id": "uuid",
561
+ "equipment_type": "ONT",
562
+ "equipment_name": "Huawei HG8145V5",
563
+ "item_type": "equipment",
564
+ "quantity_received": 100,
565
+ "received_date": "2025-01-20",
566
+ "supplier_name": "TechSupply Ltd",
567
+ "unit_cost": 2500,
568
+ "currency": "KES"
569
+ }
570
+ ```
571
+
572
+ #### List Regional Distributions
573
+ ```
574
+ GET /api/v1/inventory/distributions
575
+ Authorization: Bearer {token}
576
+
577
+ Query Parameters:
578
+ - page (int, default: 1)
579
+ - page_size (int, default: 50)
580
+ - project_id (UUID, optional)
581
+ - region_id (UUID, optional)
582
+ - inventory_id (UUID, optional)
583
+ - item_type (string, optional)
584
+ - is_active (boolean, optional)
585
+ ```
586
+
587
+ **Response:** Inventory distributed to regional hubs
588
+
589
+ #### Distribute Inventory to Regional Hub
590
+ ```
591
+ POST /api/v1/inventory/distributions
592
+ Authorization: Bearer {token}
593
+ Content-Type: application/json
594
+
595
+ Body:
596
+ {
597
+ "inventory_id": "uuid",
598
+ "project_region_id": "uuid",
599
+ "quantity_distributed": 20,
600
+ "distributed_date": "2025-01-20",
601
+ "notes": "Distribution to Nairobi hub"
602
+ }
603
+ ```
604
+
605
+ #### List Inventory Assignments (Issued to Agents)
606
+ ```
607
+ GET /api/v1/inventory/assignments
608
+ Authorization: Bearer {token}
609
+
610
+ Query Parameters:
611
+ - page (int, default: 1)
612
+ - page_size (int, default: 50)
613
+ - user_id (UUID, optional)
614
+ - region_id (UUID, optional)
615
+ - status (string, optional)
616
+ - is_returned (boolean, optional)
617
+ - ticket_id (UUID, optional)
618
+ ```
619
+
620
+ **Response:** Equipment issued to field agents
621
+
622
+ ---
623
+
624
+ ### 9. Payroll Management
625
+
626
+ #### List Payroll Records
627
+ ```
628
+ GET /api/v1/payroll
629
+ Authorization: Bearer {token}
630
+
631
+ Query Parameters:
632
+ - skip (int, default: 0)
633
+ - limit (int, default: 50, max: 100)
634
+ - user_id (UUID, optional)
635
+ - project_id (UUID, optional)
636
+ - period_start (date, optional)
637
+ - period_end (date, optional)
638
+ - status (string, optional)
639
+ ```
640
+
641
+ **Response:**
642
+ - `items[]` - Payroll records
643
+ - `total`, `skip`, `limit`
644
+
645
+ **Key Fields per Record:**
646
+ - `id`, `user_name`, `period_start`, `period_end`
647
+ - `total_earnings`, `deductions`, `net_pay`
648
+ - `status`, `payment_status`
649
+
650
+ #### Generate Payroll
651
+ ```
652
+ POST /api/v1/payroll/generate
653
+ Authorization: Bearer {token}
654
+ Content-Type: application/json
655
+
656
+ Body:
657
+ {
658
+ "project_id": "uuid",
659
+ "period_start": "2025-01-01",
660
+ "period_end": "2025-01-31",
661
+ "user_ids": ["uuid1", "uuid2"]
662
+ }
663
+ ```
664
+
665
+ **Response:** Generated payroll records
666
+
667
+ #### Approve Payroll
668
+ ```
669
+ POST /api/v1/payroll/{payroll_id}/approve
670
+ Authorization: Bearer {token}
671
+ Content-Type: application/json
672
+
673
+ Body:
674
+ {
675
+ "notes": "Approved for payment"
676
+ }
677
+ ```
678
+
679
+ ---
680
+
681
+ ### 10. Timesheet Management
682
+
683
+ #### List Timesheets
684
+ ```
685
+ GET /api/v1/timesheets
686
+ Authorization: Bearer {token}
687
+
688
+ Query Parameters:
689
+ - skip (int, default: 0)
690
+ - limit (int, default: 50, max: 100)
691
+ - user_id (UUID, optional)
692
+ - project_id (UUID, optional)
693
+ - from_date (date, optional)
694
+ - to_date (date, optional)
695
+ - status (string, optional) - "present", "absent", "on_leave", "sick_leave", "half_day"
696
+ ```
697
+
698
+ #### Get Timesheet Statistics
699
+ ```
700
+ GET /api/v1/timesheets/stats
701
+ Authorization: Bearer {token}
702
+
703
+ Query Parameters:
704
+ - user_id (UUID, optional)
705
+ - project_id (UUID, optional)
706
+ - from_date (date, optional)
707
+ - to_date (date, optional)
708
+ ```
709
+
710
+ **Response:** Attendance metrics, days worked, absences
711
+
712
+ ---
713
+
714
+ ### 11. User Management
715
+
716
+ #### List Users
717
+ ```
718
+ GET /api/v1/users
719
+ Authorization: Bearer {token}
720
+
721
+ Query Parameters:
722
+ - skip (int, default: 0)
723
+ - limit (int, default: 50, max: 100)
724
+ - role (string, optional)
725
+ - client_id (UUID, optional)
726
+ - contractor_id (UUID, optional)
727
+ - is_active (boolean, optional)
728
+ - status (string, optional)
729
+ - search (string, optional)
730
+ ```
731
+
732
+ **Response:**
733
+ - `users[]` - Array of users
734
+ - `total`, `skip`, `limit`
735
+
736
+ #### Search Users
737
+ ```
738
+ GET /api/v1/users/search
739
+ Authorization: Bearer {token}
740
+
741
+ Query Parameters:
742
+ - q (string, required) - Search query
743
+ - role (string, optional)
744
+ - limit (int, default: 20)
745
+ ```
746
+
747
+ **Response:** Matching users (useful for assignment dropdowns)
748
+
749
+ #### Invite New User
750
+ ```
751
+ POST /api/v1/invitations
752
+ Authorization: Bearer {token}
753
+ Content-Type: application/json
754
+
755
+ Body:
756
+ {
757
+ "email": "john@example.com",
758
+ "name": "John Doe",
759
+ "phone": "+254712345678",
760
+ "role": "field_agent",
761
+ "contractor_id": "uuid"
762
+ }
763
+ ```
764
+
765
+ ---
766
+
767
+ ### 12. Map & Location Services
768
+
769
+ #### Get Map Entities
770
+ ```
771
+ GET /api/v1/map/entities
772
+ Authorization: Bearer {token}
773
+
774
+ Query Parameters:
775
+ - project_id (UUID, required)
776
+ - entity_types (array, optional) - ["customers", "tickets", "sales_orders", "agents", "regions"]
777
+ - status (string, optional)
778
+ ```
779
+
780
+ **Response:**
781
+ - `customers[]` - Customer locations
782
+ - `tickets[]` - Ticket locations
783
+ - `sales_orders[]` - Sales order locations
784
+ - `agents[]` - Agent current locations
785
+ - `regions[]` - Regional hub locations
786
+
787
+ **Use Case:** Render all entities on map view
788
+
789
+ #### Get Regional Hub Locations
790
+ ```
791
+ GET /api/v1/map/regions/{project_id}
792
+ Authorization: Bearer {token}
793
+
794
+ Query Parameters:
795
+ - include_inactive (boolean, default: false)
796
+ ```
797
+
798
+ **Response:** Regional hubs with coordinates, coverage radius, active tickets/agents count
799
+
800
+ #### Get Journey Details
801
+ ```
802
+ GET /api/v1/map/journey/{assignment_id}
803
+ Authorization: Bearer {token}
804
+ ```
805
+
806
+ **Response:**
807
+ - Timeline (start, arrival, completion times)
808
+ - GPS breadcrumb trail (array of coordinates with timestamps)
809
+ - Journey statistics (distance, duration, speed)
810
+ - Location information
811
+
812
+ **Use Case:** Track agent movement during work assignment
813
+
814
+ #### Find Nearest Regional Hub
815
+ ```
816
+ GET /api/v1/map/nearest-region
817
+ Authorization: Bearer {token}
818
+
819
+ Query Parameters:
820
+ - project_id (UUID, required)
821
+ - latitude (float, required)
822
+ - longitude (float, required)
823
+ - max_distance_km (float, optional)
824
+ ```
825
+
826
+ **Response:** Nearest regional hub with distance
827
+
828
+ ---
829
+
830
+ ### 13. Task Management
831
+
832
+ #### List Tasks
833
+ ```
834
+ GET /api/v1/tasks
835
+ Authorization: Bearer {token}
836
+
837
+ Query Parameters:
838
+ - skip (int, default: 0)
839
+ - limit (int, default: 50, max: 100)
840
+ - project_id (UUID, optional)
841
+ - status (string, optional) - "pending", "assigned", "in_progress", "completed", "cancelled", "blocked"
842
+ - assigned_to (UUID, optional)
843
+ - priority (string, optional)
844
+ - from_date (date, optional)
845
+ - to_date (date, optional)
846
+ ```
847
+
848
+ #### Create Task
849
+ ```
850
+ POST /api/v1/tasks
851
+ Authorization: Bearer {token}
852
+ Content-Type: application/json
853
+
854
+ Body:
855
+ {
856
+ "project_id": "uuid",
857
+ "task_type": "installation",
858
+ "title": "Install fiber cable",
859
+ "description": "Install cable from pole A to B",
860
+ "priority": "high",
861
+ "due_date": "2025-01-25",
862
+ "assigned_to": "uuid"
863
+ }
864
+ ```
865
+
866
+ ---
867
+
868
+ ### 14. Customer Management
869
+
870
+ #### List Customers
871
+ ```
872
+ GET /api/v1/customers
873
+ Authorization: Bearer {token}
874
+
875
+ Query Parameters:
876
+ - skip (int, default: 0)
877
+ - limit (int, default: 50, max: 100)
878
+ - client_id (UUID, optional)
879
+ - search (string, optional)
880
+ - phone (string, optional)
881
+ ```
882
+
883
+ #### Get Customer Details
884
+ ```
885
+ GET /api/v1/customers/{customer_id}
886
+ Authorization: Bearer {token}
887
+ ```
888
+
889
+ **Response:** Customer profile with all related data (subscriptions, tickets, sales orders)
890
+
891
+ ---
892
+
893
+ ### 15. Notifications
894
+
895
+ #### List Notifications
896
+ ```
897
+ GET /api/v1/notifications
898
+ Authorization: Bearer {token}
899
+
900
+ Query Parameters:
901
+ - skip (int, default: 0)
902
+ - limit (int, default: 50)
903
+ - is_read (boolean, optional)
904
+ - type (string, optional)
905
+ ```
906
+
907
+ #### Get Unread Count
908
+ ```
909
+ GET /api/v1/notifications/unread-count
910
+ Authorization: Bearer {token}
911
+ ```
912
+
913
+ **Response:** `{ "count": 5 }`
914
+
915
+ #### Mark Notification as Read
916
+ ```
917
+ PUT /api/v1/notifications/{notification_id}/read
918
+ Authorization: Bearer {token}
919
+ ```
920
+
921
+ ---
922
+
923
+ ## Authentication
924
+
925
+ All endpoints require Bearer token authentication:
926
+
927
+ ```
928
+ Authorization: Bearer {access_token}
929
+ ```
930
+
931
+ **Token Refresh:**
932
+ ```
933
+ POST /api/v1/auth/refresh
934
+ Content-Type: application/json
935
+
936
+ Body:
937
+ {
938
+ "refresh_token": "your_refresh_token"
939
+ }
940
+ ```
941
+
942
+ **Response:**
943
+ ```json
944
+ {
945
+ "access_token": "new_access_token",
946
+ "refresh_token": "new_refresh_token",
947
+ "token_type": "bearer",
948
+ "expires_in": 3600
949
+ }
950
+ ```
951
+
952
+ ---
953
+
954
+ ## Error Handling
955
+
956
+ All endpoints follow standard HTTP status codes:
957
+
958
+ - `200 OK` - Success
959
+ - `201 Created` - Resource created
960
+ - `204 No Content` - Success with no response body
961
+ - `400 Bad Request` - Invalid input
962
+ - `401 Unauthorized` - Missing or invalid token
963
+ - `403 Forbidden` - Insufficient permissions
964
+ - `404 Not Found` - Resource not found
965
+ - `409 Conflict` - Duplicate or conflicting resource
966
+ - `422 Unprocessable Entity` - Validation error
967
+ - `500 Internal Server Error` - Server error
968
+
969
+ **Error Response Format:**
970
+ ```json
971
+ {
972
+ "detail": "Error message here"
973
+ }
974
+ ```
975
+
976
+ ---
977
+
978
+ ## Pagination
979
+
980
+ List endpoints use offset-based pagination:
981
+
982
+ **Request:**
983
+ - `skip` - Number of items to skip (default: 0)
984
+ - `limit` - Number of items to return (default: 50, max varies by endpoint)
985
+
986
+ **Response:**
987
+ - `items[]` or `users[]` or similar - Array of results
988
+ - `total` - Total count of items
989
+ - `skip` - Current offset
990
+ - `limit` - Current limit
991
+
992
+ ---
993
+
994
+ ## Date/Time Formats
995
+
996
+ - **Dates:** ISO 8601 format `YYYY-MM-DD` (e.g., `2025-01-20`)
997
+ - **DateTimes:** ISO 8601 with timezone `YYYY-MM-DDTHH:MM:SSZ` (e.g., `2025-01-20T14:30:00Z`)
998
+ - **Time Slots:** `"morning"`, `"afternoon"`, `"evening"`, `"any"`
999
+
1000
+ ---
1001
+
1002
+ ## Filtering Best Practices
1003
+
1004
+ 1. **Combine filters** - Most list endpoints support multiple filters simultaneously
1005
+ 2. **Use pagination** - Always paginate large result sets
1006
+ 3. **Cache where appropriate** - Dashboard stats can be cached for 1-5 minutes
1007
+ 4. **Real-time updates** - Use polling or WebSockets for live data (tickets, assignments)
1008
+
1009
+ ---
1010
+
1011
+ ## Common UI Patterns
1012
+
1013
+ ### Dashboard Widgets
1014
+ - Fetch stats on page load
1015
+ - Refresh every 30-60 seconds for live data
1016
+ - Show loading skeletons during fetch
1017
+
1018
+ ### List Views
1019
+ - Implement infinite scroll or traditional pagination
1020
+ - Add filters in sidebar or top bar
1021
+ - Show total count and current range
1022
+
1023
+ ### Map Views
1024
+ - Lazy load entities based on viewport
1025
+ - Cluster markers when zoomed out
1026
+ - Show details on marker click
1027
+
1028
+ ### Approval Workflows
1029
+ - Show pending count badge
1030
+ - Provide bulk approve/reject actions
1031
+ - Confirm destructive actions (reject, cancel)
1032
+
1033
+ ---
1034
+
1035
+ ## Performance Recommendations
1036
+
1037
+ 1. **Lazy load** - Don't fetch all data at once
1038
+ 2. **Debounce searches** - Wait 300ms before searching
1039
+ 3. **Cache reference data** - Roles, statuses, regions rarely change
1040
+ 4. **Optimize map rendering** - Use clustering for large datasets
1041
+ 5. **Batch operations** - Use bulk endpoints when available
1042
+
1043
+ ---
1044
+
1045
+ ## Support & Questions
1046
+
1047
+ For API questions or issues:
1048
+ - Backend Team Lead: [Contact Info]
1049
+ - API Documentation: `/api/v1/docs` (Swagger UI)
1050
+ - Base URL: `https://api.swiftops.example.com`
1051
+
1052
+ ---
1053
+
1054
+ **End of Document**
docs/api/dashboards/pm/PM_DASHBOARD_DESIGN_GUIDE.md ADDED
@@ -0,0 +1,604 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Project Manager Dashboard - Design & UX Guide
2
+
3
+ **Version:** 1.0
4
+ **Last Updated:** 2025-11-19
5
+ **Audience:** Frontend Development Team, UI/UX Designers
6
+
7
+ ---
8
+
9
+ ## Executive Summary
10
+
11
+ The Project Manager (PM) dashboard is the command center for daily field service operations. It provides real-time visibility across sales, operations, finance, and resources, enabling PMs to orchestrate work efficiently.
12
+
13
+ ### Key Design Principles
14
+
15
+ 1. **Information at a Glance** - Critical metrics visible without scrolling
16
+ 2. **Action-Oriented** - Every metric has a corresponding action
17
+ 3. **Context-Aware** - Show relevant data based on time, location, status
18
+ 4. **Progressive Disclosure** - Summary → Details → Actions
19
+ 5. **Real-Time Updates** - Live data for time-sensitive operations
20
+
21
+ ---
22
+
23
+ ## User Persona: The Project Manager
24
+
25
+ ### Daily Workflow
26
+
27
+ **Morning (8:00 AM - 10:00 AM)**
28
+ - Review overnight sales orders
29
+ - Check today's scheduled tickets
30
+ - Approve pending expenses from yesterday
31
+ - Assign unassigned tickets to field agents
32
+ - Check inventory levels
33
+
34
+ **Midday (10:00 AM - 2:00 PM)**
35
+ - Monitor active tickets in progress
36
+ - Handle reassignments (agent issues, emergencies)
37
+ - Approve expense claims as they come in
38
+ - Respond to customer escalations
39
+ - Track agent locations on map
40
+
41
+ **Afternoon (2:00 PM - 5:00 PM)**
42
+ - Review completed tickets
43
+ - Generate invoices for completed work
44
+ - Process payroll for the period
45
+ - Plan tomorrow's assignments
46
+ - Review financial position
47
+
48
+ ### Pain Points to Solve
49
+
50
+ ❌ **Too many clicks** - Accessing critical info requires navigation
51
+ ❌ **No overview** - Can't see overall status at a glance
52
+ ❌ **Manual tracking** - Spreadsheets for inventory, assignments
53
+ ❌ **Delayed approvals** - Expenses pile up, agents wait for payment
54
+ ❌ **Poor visibility** - Don't know where agents are or what they're doing
55
+
56
+ ---
57
+
58
+ ## Dashboard Layout
59
+
60
+ ### Recommended Structure
61
+
62
+ ```
63
+ ┌─────────────────────────────────────────────────────────────────┐
64
+ │ HEADER: SwiftOps | PM Dashboard | [Notifications] [Profile] │
65
+ ├─────────────────────────────────────────────────────────────────┤
66
+ │ │
67
+ │ ┌─────────────────────────────────────────────────────────┐ │
68
+ │ │ TODAY'S OVERVIEW (4 metric cards) │ │
69
+ │ │ [Open Tickets] [Active Agents] [Overdue] [Pending $] │ │
70
+ │ └─────────────────────────────────────────────────────────┘ │
71
+ │ │
72
+ │ ┌─────────────────────────────────────────────────────────┐ │
73
+ │ │ FINANCIAL SNAPSHOT (1 card, 4 metrics) │ │
74
+ │ │ Cash | Pending Expenses | Unpaid Invoices | Payroll │ │
75
+ │ └─────────────────────────────────────────────────────────┘ │
76
+ │ │
77
+ │ ┌─────────────────────────────────────────────────────────┐ │
78
+ │ │ QUICK ACTIONS (6 buttons) │ │
79
+ │ │ [Assign Tickets] [Approve Expenses] [Add Inventory] │ │
80
+ │ │ [Generate Payroll] [Create Invoice] [Add User] │ │
81
+ │ └─────────────────────────────────────────────────────────┘ │
82
+ │ │
83
+ │ ┌───────────────────────────┬─────────────────────────────┐ │
84
+ │ │ PENDING SALES ORDERS │ INVENTORY STATUS │ │
85
+ │ │ (List with actions) │ (Stock levels + alerts) │ │
86
+ │ │ │ │ │
87
+ │ │ 15 orders pending │ ONTs: 45 ⚠️ Low │ │
88
+ │ │ [View All] [Bulk Assign] │ Routers: 120 ✓ │ │
89
+ │ └───────────────────────────┴─────────────────────────────┘ │
90
+ │ │
91
+ │ ┌─────────────────────────────────────────────────────────┐ │
92
+ │ │ ACTIVE TICKETS MAP │ │
93
+ │ │ (Interactive map showing tickets, agents, regions) │ │
94
+ │ │ [Full Screen] [Filters] │ │
95
+ │ └─────────────────────────────────────────────────────────┘ │
96
+ │ │
97
+ │ ┌───────────────────────────┬─────────────────────────────┐ │
98
+ │ │ PENDING APPROVALS │ TEAM STATUS │ │
99
+ │ │ (Expenses, Payroll) │ (Agent availability) │ │
100
+ │ └───────────────────────────┴─────────────────────────────┘ │
101
+ │ │
102
+ └─────────────────────────────────────────────────────────────────┘
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Component Specifications
108
+
109
+ ### 1. Today's Overview Cards
110
+
111
+ **Purpose:** At-a-glance metrics for daily operations
112
+
113
+ **Layout:** 4 cards in a row (responsive: 2x2 on tablet, stacked on mobile)
114
+
115
+ **Card 1: Open Tickets**
116
+ - **Primary Metric:** Count of unassigned tickets
117
+ - **Secondary Info:** "12 need assignment"
118
+ - **Action:** Click → Navigate to tickets page with filter `status=open`
119
+ - **Visual:** Orange/amber color if > 10, green if < 5
120
+ - **API:** `GET /tickets/stats`
121
+
122
+ **Card 2: Active Agents**
123
+ - **Primary Metric:** Count of agents currently working
124
+ - **Secondary Info:** "8 out of 25 agents"
125
+ - **Action:** Click → Navigate to team page
126
+ - **Visual:** Progress bar showing utilization
127
+ - **API:** `GET /ticket-assignments?status=in_progress` (count unique users)
128
+
129
+ **Card 3: Overdue Tickets**
130
+ - **Primary Metric:** Count of overdue tickets
131
+ - **Secondary Info:** "3 past SLA"
132
+ - **Action:** Click → Navigate to tickets page with filter `is_overdue=true`
133
+ - **Visual:** Red color if > 0, green if 0
134
+ - **API:** `GET /tickets/stats` (overdue_tickets field)
135
+
136
+ **Card 4: Pending Expenses**
137
+ - **Primary Metric:** Count of pending expense approvals
138
+ - **Secondary Info:** "KES 25,000 total"
139
+ - **Action:** Click → Navigate to expenses page with filter `approval_status=pending`
140
+ - **Visual:** Badge with count
141
+ - **API:** `GET /expenses/stats`
142
+
143
+ ### 2. Financial Snapshot Card
144
+
145
+ **Purpose:** Quick view of financial position
146
+
147
+ **Layout:** Single card with 4 metrics in a row
148
+
149
+ **Metrics:**
150
+ 1. **Cash Position** - Current available funds
151
+ 2. **Pending Expenses** - Awaiting approval
152
+ 3. **Unpaid Invoices** - Owed to contractors
153
+ 4. **Payroll Due** - Upcoming payroll obligations
154
+
155
+ **Data Sources:**
156
+ - `GET /finance/cash-flow/{project_id}`
157
+ - `GET /expenses/stats`
158
+ - `GET /invoices?unpaid_only=true`
159
+ - `GET /payroll?status=approved&payment_status=pending`
160
+
161
+ **Visual Design:**
162
+ - Green for positive cash flow
163
+ - Amber for low cash warnings
164
+ - Red for negative/critical
165
+
166
+ ### 3. Quick Actions Bar
167
+
168
+ **Purpose:** One-click access to common PM tasks
169
+
170
+ **Layout:** 6 buttons in 2 rows (responsive: 3x2 on tablet, stacked on mobile)
171
+
172
+ **Buttons:**
173
+ 1. **Assign Tickets** → Opens ticket assignment modal
174
+ 2. **Approve Expenses** → Opens expense approval queue
175
+ 3. **Add Inventory** → Opens inventory creation form
176
+ 4. **Generate Payroll** → Opens payroll generation wizard
177
+ 5. **Create Invoice** → Opens invoice creation form
178
+ 6. **Add User** → Opens user invitation form
179
+
180
+ **Design:**
181
+ - Icon + Label
182
+ - Hover state shows tooltip with description
183
+ - Disabled state if no pending items (e.g., "Approve Expenses" disabled if none pending)
184
+
185
+ ### 4. Pending Sales Orders Widget
186
+
187
+ **Purpose:** Convert sales orders to work tickets
188
+
189
+ **Layout:** List view with inline actions
190
+
191
+ **Display:**
192
+ - Show top 5 pending orders
193
+ - Each row: Customer name, package, location, price
194
+ - Actions per row: [Assign Region] [Convert to Ticket]
195
+ - Footer: "15 total" + [View All] [Bulk Convert]
196
+
197
+ **API:** `GET /sales-orders?pending_processing=true&limit=5`
198
+
199
+ **Interactions:**
200
+ - **Assign Region** → Opens region selector dropdown
201
+ - **Convert to Ticket** → Opens ticket creation modal (pre-filled with order data)
202
+ - **Bulk Convert** → Opens multi-select modal for batch conversion
203
+
204
+ **Visual Indicators:**
205
+ - ⚠️ No region assigned
206
+ - ⚠️ No location coordinates
207
+ - ✓ Ready to convert
208
+
209
+ ### 5. Inventory Status Widget
210
+
211
+ **Purpose:** Monitor stock levels and prevent shortages
212
+
213
+ **Layout:** Compact list with progress bars
214
+
215
+ **Display:**
216
+ - Equipment type + quantity + status indicator
217
+ - Progress bar showing available vs. total
218
+ - Alert icon for low stock (< 20% remaining)
219
+
220
+ **Example:**
221
+ ```
222
+ ONTs: [████░░░░░░] 45 / 200 ⚠️ Low
223
+ Routers: [████████░░] 120 / 150 ✓
224
+ Cables: [██████████] 200 / 200 ✓
225
+ ```
226
+
227
+ **API:** `GET /inventory?project_id={id}`
228
+
229
+ **Actions:**
230
+ - [Distribute to Hubs] → Opens distribution modal
231
+ - [Add Stock] → Opens inventory creation form
232
+
233
+ **Alert Thresholds:**
234
+ - Red: < 10% remaining
235
+ - Amber: < 20% remaining
236
+ - Green: > 20% remaining
237
+
238
+ ### 6. Active Tickets Map
239
+
240
+ **Purpose:** Geographic visualization of operations
241
+
242
+ **Layout:** Interactive map (Google Maps, Mapbox, or Leaflet)
243
+
244
+ **Map Layers:**
245
+ 1. **Regional Hubs** - Blue markers with coverage circles
246
+ 2. **Open Tickets** - Red markers
247
+ 3. **In-Progress Tickets** - Yellow markers
248
+ 4. **Completed Tickets** - Green markers
249
+ 5. **Field Agents** - Agent icons with real-time location
250
+ 6. **Sales Orders** - Purple markers (pending installation sites)
251
+
252
+ **API:** `GET /map/entities?project_id={id}&entity_types=tickets,agents,regions,sales_orders`
253
+
254
+ **Interactions:**
255
+ - Click marker → Show popup with entity details
256
+ - Click agent → Show current assignment + journey trail
257
+ - Filter by entity type (toggle layers)
258
+ - [Full Screen] button → Expand to full page
259
+
260
+ **Performance:**
261
+ - Use marker clustering for > 50 markers
262
+ - Lazy load markers based on viewport
263
+ - Update agent positions every 30 seconds
264
+
265
+ ### 7. Pending Approvals Widget
266
+
267
+ **Purpose:** Queue of items requiring PM approval
268
+
269
+ **Layout:** Tabbed interface or segmented list
270
+
271
+ **Tabs:**
272
+ 1. **Expenses** (count badge)
273
+ 2. **Payroll** (count badge)
274
+ 3. **Invoices** (count badge)
275
+
276
+ **Display per Tab:**
277
+ - List of pending items (top 5)
278
+ - Each row: Submitter, amount, date, [Approve] [Reject]
279
+ - Footer: "12 total" + [View All]
280
+
281
+ **APIs:**
282
+ - `GET /expenses?approval_status=pending&limit=5`
283
+ - `GET /payroll?status=pending&limit=5`
284
+ - `GET /invoices?status=draft&limit=5`
285
+
286
+ **Bulk Actions:**
287
+ - [Approve All] - Approve all visible items
288
+ - [Review Queue] - Navigate to full approval page
289
+
290
+ ### 8. Team Status Widget
291
+
292
+ **Purpose:** Monitor agent availability and workload
293
+
294
+ **Layout:** List or grid of agents
295
+
296
+ **Display:**
297
+ - Agent name + photo
298
+ - Current status (Available, On Job, Off Duty)
299
+ - Current assignment (if any)
300
+ - Location (region/area)
301
+
302
+ **API:** `GET /users?role=field_agent&is_active=true`
303
+
304
+ **Status Indicators:**
305
+ - 🟢 Available - No active assignment
306
+ - 🟡 On Job - Has active assignment
307
+ - 🔴 Off Duty - Not working today
308
+ - ⚫ Offline - No recent location update
309
+
310
+ **Interactions:**
311
+ - Click agent → View profile + assignment history
312
+ - Filter by status, region
313
+
314
+ ---
315
+
316
+ ## User Flows
317
+
318
+ ### Flow 1: Morning Routine - Review & Assign
319
+
320
+ 1. **PM logs in** → Dashboard loads
321
+ 2. **Sees "12 Open Tickets"** → Clicks card
322
+ 3. **Tickets page opens** → Filtered to `status=open`
323
+ 4. **Reviews first ticket** → Clicks "Assign"
324
+ 5. **Assignment modal opens** → Shows available agents
325
+ 6. **Selects agent** → Clicks "Assign"
326
+ 7. **Ticket assigned** → Notification sent to agent
327
+ 8. **Returns to dashboard** → Counter updates to "11 Open Tickets"
328
+
329
+ **API Sequence:**
330
+ ```
331
+ 1. GET /tickets/stats
332
+ 2. GET /tickets?status=open
333
+ 3. GET /ticket-assignments/available-agents?ticket_id={id}
334
+ 4. POST /ticket-assignments
335
+ 5. GET /tickets/stats (refresh)
336
+ ```
337
+
338
+ ### Flow 2: Convert Sales Order to Ticket
339
+
340
+ 1. **PM sees "15 Pending Sales Orders"** → Reviews list
341
+ 2. **Clicks "Convert to Ticket"** on an order
342
+ 3. **Modal opens** → Pre-filled with order data
343
+ 4. **Selects priority, schedule** → Clicks "Create Ticket"
344
+ 5. **Ticket created** → Order marked as processed
345
+ 6. **Dashboard updates** → "14 Pending Sales Orders"
346
+
347
+ **API Sequence:**
348
+ ```
349
+ 1. GET /sales-orders?pending_processing=true
350
+ 2. POST /sales-orders/{id}/promote
351
+ 3. GET /sales-orders?pending_processing=true (refresh)
352
+ ```
353
+
354
+ ### Flow 3: Approve Expenses
355
+
356
+ 1. **PM sees "5 Pending Expenses"** → Clicks widget
357
+ 2. **Expense approval page opens**
358
+ 3. **Reviews first expense** → Checks receipt, location
359
+ 4. **Clicks "Approve"** → Adds approval note
360
+ 5. **Expense approved** → Agent notified
361
+ 6. **Returns to dashboard** → "4 Pending Expenses"
362
+
363
+ **API Sequence:**
364
+ ```
365
+ 1. GET /expenses?approval_status=pending
366
+ 2. POST /expenses/{id}/approve
367
+ 3. GET /expenses/stats (refresh)
368
+ ```
369
+
370
+ ### Flow 4: Distribute Inventory
371
+
372
+ 1. **PM sees "ONTs: 45 ⚠️ Low"** → Clicks "Distribute to Hubs"
373
+ 2. **Distribution modal opens** → Shows main office stock
374
+ 3. **Selects region, quantity** → Clicks "Distribute"
375
+ 4. **Inventory distributed** → Hub stock updated
376
+ 5. **Dashboard updates** → "ONTs: 25 ⚠️ Low" (main office)
377
+
378
+ **API Sequence:**
379
+ ```
380
+ 1. GET /inventory?project_id={id}
381
+ 2. POST /inventory/distributions
382
+ 3. GET /inventory?project_id={id} (refresh)
383
+ ```
384
+
385
+ ### Flow 5: Track Agent on Map
386
+
387
+ 1. **PM clicks agent marker on map**
388
+ 2. **Popup shows** → Agent name, current assignment, status
389
+ 3. **Clicks "View Journey"**
390
+ 4. **Journey details load** → GPS breadcrumb trail displayed
391
+ 5. **PM sees** → Start time, arrival time, current location
392
+
393
+ **API Sequence:**
394
+ ```
395
+ 1. GET /map/entities?entity_types=agents
396
+ 2. GET /map/journey/{assignment_id}
397
+ ```
398
+
399
+ ---
400
+
401
+ ## Data Refresh Strategy
402
+
403
+ ### Real-Time Updates (Every 10-30 seconds)
404
+ - Active ticket assignments
405
+ - Agent locations on map
406
+ - Pending approvals count
407
+
408
+ ### Periodic Refresh (Every 1-5 minutes)
409
+ - Dashboard statistics
410
+ - Inventory levels
411
+ - Financial metrics
412
+
413
+ ### On-Demand Refresh
414
+ - After user action (assign ticket, approve expense)
415
+ - Manual refresh button
416
+ - Page focus/visibility change
417
+
418
+ ### Implementation Options
419
+
420
+ **Option 1: Polling**
421
+ ```javascript
422
+ // Refresh dashboard stats every 60 seconds
423
+ setInterval(() => {
424
+ fetchDashboardStats();
425
+ }, 60000);
426
+ ```
427
+
428
+ **Option 2: WebSockets** (Future Enhancement)
429
+ ```javascript
430
+ // Real-time updates via WebSocket
431
+ socket.on('ticket_assigned', (data) => {
432
+ updateDashboardStats();
433
+ });
434
+ ```
435
+
436
+ **Option 3: Server-Sent Events** (Future Enhancement)
437
+ ```javascript
438
+ // One-way real-time updates
439
+ const eventSource = new EventSource('/api/v1/notifications/stream');
440
+ eventSource.onmessage = (event) => {
441
+ handleUpdate(event.data);
442
+ };
443
+ ```
444
+
445
+ ---
446
+
447
+ ## Responsive Design
448
+
449
+ ### Desktop (> 1200px)
450
+ - Full dashboard layout as shown
451
+ - All widgets visible
452
+ - Map at comfortable size (400-600px height)
453
+
454
+ ### Tablet (768px - 1200px)
455
+ - 2-column layout for metric cards
456
+ - Stacked widgets (sales orders above inventory)
457
+ - Collapsible sidebar for filters
458
+
459
+ ### Mobile (< 768px)
460
+ - Single column layout
461
+ - Metric cards stacked
462
+ - Map hidden by default (accessible via tab)
463
+ - Bottom navigation for quick actions
464
+
465
+ ---
466
+
467
+ ## Accessibility
468
+
469
+ ### Keyboard Navigation
470
+ - All actions accessible via keyboard
471
+ - Tab order follows visual hierarchy
472
+ - Escape key closes modals
473
+
474
+ ### Screen Readers
475
+ - Proper ARIA labels on all interactive elements
476
+ - Status announcements for updates
477
+ - Descriptive button labels
478
+
479
+ ### Color Contrast
480
+ - WCAG AA compliance minimum
481
+ - Don't rely solely on color for status (use icons too)
482
+
483
+ ### Focus Management
484
+ - Clear focus indicators
485
+ - Focus trap in modals
486
+ - Return focus after modal close
487
+
488
+ ---
489
+
490
+ ## Performance Optimization
491
+
492
+ ### Initial Load
493
+ - Lazy load below-the-fold widgets
494
+ - Skeleton screens during fetch
495
+ - Critical CSS inline
496
+
497
+ ### Data Fetching
498
+ - Parallel API calls where possible
499
+ - Cache reference data (roles, statuses)
500
+ - Debounce search inputs (300ms)
501
+
502
+ ### Map Rendering
503
+ - Marker clustering for > 50 markers
504
+ - Viewport-based loading
505
+ - Throttle zoom/pan events
506
+
507
+ ### Bundle Size
508
+ - Code splitting by route
509
+ - Lazy load heavy components (map, charts)
510
+ - Tree shaking unused code
511
+
512
+ ---
513
+
514
+ ## Error Handling
515
+
516
+ ### Network Errors
517
+ - Show toast notification
518
+ - Retry button for failed requests
519
+ - Offline indicator
520
+
521
+ ### API Errors
522
+ - Display user-friendly error messages
523
+ - Log errors for debugging
524
+ - Fallback to cached data if available
525
+
526
+ ### Empty States
527
+ - "No pending sales orders" with illustration
528
+ - "All tickets assigned" success message
529
+ - "No expenses to approve" with helpful tip
530
+
531
+ ---
532
+
533
+ ## Testing Recommendations
534
+
535
+ ### Unit Tests
536
+ - Component rendering
537
+ - User interactions (clicks, form submissions)
538
+ - Data transformations
539
+
540
+ ### Integration Tests
541
+ - API call sequences
542
+ - State management
543
+ - Navigation flows
544
+
545
+ ### E2E Tests
546
+ - Critical user flows (assign ticket, approve expense)
547
+ - Cross-browser compatibility
548
+ - Mobile responsiveness
549
+
550
+ ---
551
+
552
+ ## Future Enhancements
553
+
554
+ ### Phase 2 Features
555
+ - Real-time notifications (WebSockets)
556
+ - Advanced analytics (charts, trends)
557
+ - Customizable dashboard (drag-and-drop widgets)
558
+ - Export reports (PDF, Excel)
559
+
560
+ ### Phase 3 Features
561
+ - AI-powered assignment recommendations
562
+ - Predictive inventory alerts
563
+ - Automated expense approval rules
564
+ - Voice commands for mobile
565
+
566
+ ---
567
+
568
+ ## Design Assets
569
+
570
+ ### Color Palette
571
+ - **Primary:** #1976D2 (Blue)
572
+ - **Success:** #4CAF50 (Green)
573
+ - **Warning:** #FF9800 (Amber)
574
+ - **Error:** #F44336 (Red)
575
+ - **Info:** #2196F3 (Light Blue)
576
+
577
+ ### Typography
578
+ - **Headings:** Inter, Roboto, or system font
579
+ - **Body:** Same as headings
580
+ - **Monospace:** Courier New (for IDs, codes)
581
+
582
+ ### Icons
583
+ - Use consistent icon library (Material Icons, Feather, or Heroicons)
584
+ - 24px for buttons, 16px for inline icons
585
+
586
+ ### Spacing
587
+ - Base unit: 8px
588
+ - Small: 8px, Medium: 16px, Large: 24px, XL: 32px
589
+
590
+ ---
591
+
592
+ ## Questions & Support
593
+
594
+ For design questions:
595
+ - UI/UX Lead: [Contact Info]
596
+ - Design System: [Link to Figma/Storybook]
597
+
598
+ For technical questions:
599
+ - See `PM_DASHBOARD_API_REFERENCE.md`
600
+ - Backend Team: [Contact Info]
601
+
602
+ ---
603
+
604
+ **End of Document**
docs/api/dashboards/pm/QUICK_REFERENCE.md ADDED
@@ -0,0 +1,303 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PM Dashboard - Quick Reference
2
+
3
+ **Quick lookup for common PM operations**
4
+
5
+ ---
6
+
7
+ ## 🎯 Dashboard Overview
8
+
9
+ ```
10
+ GET /api/v1/analytics/platform-admin/dashboard
11
+ → All dashboard statistics in one call
12
+ ```
13
+
14
+ ---
15
+
16
+ ## 📋 Sales Orders
17
+
18
+ | Action | Endpoint | Method |
19
+ |--------|----------|--------|
20
+ | List pending orders | `/sales-orders?pending_processing=true` | GET |
21
+ | Get stats | `/sales-orders/stats` | GET |
22
+ | Assign to region | `/sales-orders/{id}/assign-region` | POST |
23
+ | Convert to ticket | `/sales-orders/{id}/promote` | POST |
24
+ | Bulk convert | `/sales-orders/bulk-promote` | POST |
25
+
26
+ ---
27
+
28
+ ## 🎫 Tickets
29
+
30
+ | Action | Endpoint | Method |
31
+ |--------|----------|--------|
32
+ | List all tickets | `/tickets` | GET |
33
+ | Get stats | `/tickets/stats` | GET |
34
+ | Get open tickets | `/tickets?status=open` | GET |
35
+ | Get overdue | `/tickets?is_overdue=true` | GET |
36
+ | Update ticket | `/tickets/{id}` | PUT |
37
+ | Reschedule | `/tickets/{id}/reschedule` | POST |
38
+ | Cancel | `/tickets/{id}/cancel` | POST |
39
+
40
+ **Common Filters:**
41
+ - `status`: open, assigned, in_progress, pending_review, completed, cancelled
42
+ - `priority`: low, normal, high, urgent
43
+ - `ticket_type`: installation, support, infrastructure
44
+ - `project_region_id`: Filter by region
45
+
46
+ ---
47
+
48
+ ## 👥 Ticket Assignments
49
+
50
+ | Action | Endpoint | Method |
51
+ |--------|----------|--------|
52
+ | List assignments | `/ticket-assignments` | GET |
53
+ | Get available agents | `/ticket-assignments/available-agents?ticket_id={id}` | GET |
54
+ | Assign ticket | `/ticket-assignments` | POST |
55
+ | Reassign | `/ticket-assignments/{id}/reassign` | POST |
56
+
57
+ ---
58
+
59
+ ## 💰 Expenses
60
+
61
+ | Action | Endpoint | Method |
62
+ |--------|----------|--------|
63
+ | List expenses | `/expenses` | GET |
64
+ | Get stats | `/expenses/stats` | GET |
65
+ | Get pending | `/expenses?approval_status=pending` | GET |
66
+ | Approve/Reject | `/expenses/{id}/approve` | POST |
67
+ | Mark paid | `/expenses/{id}/mark-paid` | POST |
68
+
69
+ ---
70
+
71
+ ## 💵 Finance
72
+
73
+ | Action | Endpoint | Method |
74
+ |--------|----------|--------|
75
+ | List transactions | `/finance` | GET |
76
+ | Get cash flow | `/finance/cash-flow/{project_id}` | GET |
77
+ | Create transaction | `/finance` | POST |
78
+ | Approve | `/finance/{id}/approve` | POST |
79
+
80
+ ---
81
+
82
+ ## 📄 Contractor Invoices
83
+
84
+ | Action | Endpoint | Method |
85
+ |--------|----------|--------|
86
+ | List invoices | `/invoices` | GET |
87
+ | Get unpaid | `/invoices?unpaid_only=true` | GET |
88
+ | Create invoice | `/invoices` | POST |
89
+ | Add line item | `/invoices/{id}/line-items` | POST |
90
+ | Record payment | `/invoices/{id}/payments` | POST |
91
+ | Change status | `/invoices/{id}/status` | POST |
92
+
93
+ ---
94
+
95
+ ## 📦 Inventory
96
+
97
+ | Action | Endpoint | Method |
98
+ |--------|----------|--------|
99
+ | List main office | `/inventory` | GET |
100
+ | Create batch | `/inventory` | POST |
101
+ | List distributions | `/inventory/distributions` | GET |
102
+ | Distribute to hub | `/inventory/distributions` | POST |
103
+ | List assignments | `/inventory/assignments` | GET |
104
+
105
+ ---
106
+
107
+ ## 💼 Payroll
108
+
109
+ | Action | Endpoint | Method |
110
+ |--------|----------|--------|
111
+ | List payroll | `/payroll` | GET |
112
+ | Generate | `/payroll/generate` | POST |
113
+ | Approve | `/payroll/{id}/approve` | POST |
114
+
115
+ ---
116
+
117
+ ## 🗓️ Timesheets
118
+
119
+ | Action | Endpoint | Method |
120
+ |--------|----------|--------|
121
+ | List timesheets | `/timesheets` | GET |
122
+ | Get stats | `/timesheets/stats` | GET |
123
+
124
+ ---
125
+
126
+ ## 👤 Users
127
+
128
+ | Action | Endpoint | Method |
129
+ |--------|----------|--------|
130
+ | List users | `/users` | GET |
131
+ | Search | `/users/search?q={query}` | GET |
132
+ | Invite | `/invitations` | POST |
133
+
134
+ ---
135
+
136
+ ## 🗺️ Map & Location
137
+
138
+ | Action | Endpoint | Method |
139
+ |--------|----------|--------|
140
+ | Get all map entities | `/map/entities?project_id={id}` | GET |
141
+ | Get regional hubs | `/map/regions/{project_id}` | GET |
142
+ | Get journey details | `/map/journey/{assignment_id}` | GET |
143
+ | Find nearest hub | `/map/nearest-region` | GET |
144
+
145
+ ---
146
+
147
+ ## 🔔 Notifications
148
+
149
+ | Action | Endpoint | Method |
150
+ |--------|----------|--------|
151
+ | List notifications | `/notifications` | GET |
152
+ | Get unread count | `/notifications/unread-count` | GET |
153
+ | Mark as read | `/notifications/{id}/read` | PUT |
154
+
155
+ ---
156
+
157
+ ## 🔐 Authentication
158
+
159
+ ```
160
+ POST /api/v1/auth/refresh
161
+ Body: { "refresh_token": "..." }
162
+ → Returns new access_token
163
+ ```
164
+
165
+ **All requests require:**
166
+ ```
167
+ Authorization: Bearer {access_token}
168
+ ```
169
+
170
+ ---
171
+
172
+ ## 📊 Common Response Patterns
173
+
174
+ ### List Response
175
+ ```json
176
+ {
177
+ "items": [...],
178
+ "total": 150,
179
+ "skip": 0,
180
+ "limit": 50
181
+ }
182
+ ```
183
+
184
+ ### Stats Response
185
+ ```json
186
+ {
187
+ "total": 150,
188
+ "by_status": { "open": 20, "completed": 80 },
189
+ "by_type": { "installation": 100, "support": 50 }
190
+ }
191
+ ```
192
+
193
+ ### Error Response
194
+ ```json
195
+ {
196
+ "detail": "Error message"
197
+ }
198
+ ```
199
+
200
+ ---
201
+
202
+ ## ⚡ Quick Workflows
203
+
204
+ ### Assign a Ticket
205
+ ```
206
+ 1. GET /ticket-assignments/available-agents?ticket_id={id}
207
+ 2. POST /ticket-assignments
208
+ Body: { "ticket_id": "...", "user_id": "..." }
209
+ ```
210
+
211
+ ### Convert Sales Order to Ticket
212
+ ```
213
+ 1. GET /sales-orders?pending_processing=true
214
+ 2. POST /sales-orders/{id}/promote
215
+ Body: { "priority": "normal", "scheduled_date": "..." }
216
+ ```
217
+
218
+ ### Approve Expense
219
+ ```
220
+ 1. GET /expenses?approval_status=pending
221
+ 2. POST /expenses/{id}/approve
222
+ Body: { "approved": true, "notes": "..." }
223
+ ```
224
+
225
+ ### Distribute Inventory
226
+ ```
227
+ 1. GET /inventory?project_id={id}
228
+ 2. POST /inventory/distributions
229
+ Body: { "inventory_id": "...", "project_region_id": "...", "quantity_distributed": 20 }
230
+ ```
231
+
232
+ ### Generate Payroll
233
+ ```
234
+ 1. GET /timesheets?from_date=...&to_date=...
235
+ 2. POST /payroll/generate
236
+ Body: { "project_id": "...", "period_start": "...", "period_end": "..." }
237
+ ```
238
+
239
+ ---
240
+
241
+ ## 🎨 Status Values
242
+
243
+ ### Ticket Status
244
+ - `open` - Not assigned
245
+ - `assigned` - Assigned to agent
246
+ - `in_progress` - Agent working on it
247
+ - `pending_review` - Awaiting review
248
+ - `completed` - Done
249
+ - `cancelled` - Cancelled
250
+
251
+ ### Sales Order Status
252
+ - `pending` - Awaiting processing
253
+ - `processed` - Converted to ticket
254
+ - `cancelled` - Cancelled
255
+ - `duplicate` - Marked as duplicate
256
+
257
+ ### Expense Approval Status
258
+ - `pending` - Awaiting approval
259
+ - `approved` - Approved
260
+ - `rejected` - Rejected
261
+
262
+ ### Payment Status
263
+ - `pending` - Not paid
264
+ - `paid` - Paid
265
+
266
+ ---
267
+
268
+ ## 📅 Date Formats
269
+
270
+ - **Date:** `YYYY-MM-DD` (e.g., `2025-01-20`)
271
+ - **DateTime:** `YYYY-MM-DDTHH:MM:SSZ` (e.g., `2025-01-20T14:30:00Z`)
272
+ - **Time Slots:** `morning`, `afternoon`, `evening`, `any`
273
+
274
+ ---
275
+
276
+ ## 🔢 Pagination
277
+
278
+ Default: `skip=0&limit=50`
279
+
280
+ Example: `/tickets?skip=0&limit=50`
281
+
282
+ ---
283
+
284
+ ## 🎯 Priority Levels
285
+
286
+ - `low` - Can wait
287
+ - `normal` - Standard priority
288
+ - `high` - Important
289
+ - `urgent` - Immediate attention
290
+
291
+ ---
292
+
293
+ ## 📱 Base URL
294
+
295
+ ```
296
+ https://api.swiftops.example.com/api/v1
297
+ ```
298
+
299
+ ---
300
+
301
+ **For detailed documentation, see:**
302
+ - `PM_DASHBOARD_API_REFERENCE.md` - Full API details
303
+ - `PM_DASHBOARD_DESIGN_GUIDE.md` - UX and design specs
docs/api/dashboards/pm/README.md ADDED
@@ -0,0 +1,376 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Project Manager Dashboard Documentation
2
+
3
+ **Complete documentation package for building the PM dashboard**
4
+
5
+ ---
6
+
7
+ ## 📚 Documentation Overview
8
+
9
+ This directory contains comprehensive documentation for implementing the Project Manager (PM) dashboard in the SwiftOps platform.
10
+
11
+ ### Documents in This Package
12
+
13
+ 1. **[PM_DASHBOARD_API_REFERENCE.md](./PM_DASHBOARD_API_REFERENCE.md)** ⭐ **START HERE**
14
+ - Complete API endpoint reference
15
+ - Request/response formats
16
+ - Query parameters and filters
17
+ - Authentication and error handling
18
+ - **Audience:** Frontend developers
19
+
20
+ 2. **[PM_DASHBOARD_DESIGN_GUIDE.md](./PM_DASHBOARD_DESIGN_GUIDE.md)**
21
+ - Dashboard layout and structure
22
+ - Component specifications
23
+ - User flows and interactions
24
+ - Responsive design guidelines
25
+ - **Audience:** UI/UX designers, frontend developers
26
+
27
+ 3. **[QUICK_REFERENCE.md](./QUICK_REFERENCE.md)**
28
+ - Cheat sheet for common operations
29
+ - Quick endpoint lookup
30
+ - Common workflows
31
+ - Status values and formats
32
+ - **Audience:** All team members
33
+
34
+ ---
35
+
36
+ ## 🎯 What is the PM Dashboard?
37
+
38
+ The Project Manager dashboard is the **command center** for daily field service operations. It provides:
39
+
40
+ - **Real-time visibility** across sales, operations, finance, and resources
41
+ - **Action-oriented interface** for quick decision-making
42
+ - **Geographic visualization** of field operations
43
+ - **Approval workflows** for expenses, payroll, and invoices
44
+ - **Resource management** for inventory and team allocation
45
+
46
+ ### Key Capabilities
47
+
48
+ ✅ Convert sales orders to work tickets
49
+ ✅ Assign tickets to field agents
50
+ ✅ Approve expenses and track payments
51
+ ✅ Monitor inventory levels and distributions
52
+ ✅ Generate payroll and contractor invoices
53
+ ✅ Track agent locations and journeys on map
54
+ ✅ View real-time operational metrics
55
+
56
+ ---
57
+
58
+ ## 🚀 Getting Started
59
+
60
+ ### For Frontend Developers
61
+
62
+ 1. **Read the API Reference** - [PM_DASHBOARD_API_REFERENCE.md](./PM_DASHBOARD_API_REFERENCE.md)
63
+ - Understand available endpoints
64
+ - Review request/response formats
65
+ - Note authentication requirements
66
+
67
+ 2. **Review the Design Guide** - [PM_DASHBOARD_DESIGN_GUIDE.md](./PM_DASHBOARD_DESIGN_GUIDE.md)
68
+ - Understand dashboard layout
69
+ - Review component specifications
70
+ - Study user flows
71
+
72
+ 3. **Use the Quick Reference** - [QUICK_REFERENCE.md](./QUICK_REFERENCE.md)
73
+ - Keep handy during development
74
+ - Quick endpoint lookup
75
+ - Common workflow patterns
76
+
77
+ ### For UI/UX Designers
78
+
79
+ 1. **Start with Design Guide** - [PM_DASHBOARD_DESIGN_GUIDE.md](./PM_DASHBOARD_DESIGN_GUIDE.md)
80
+ - Dashboard structure and layout
81
+ - Component specifications
82
+ - User personas and workflows
83
+
84
+ 2. **Reference API capabilities** - [PM_DASHBOARD_API_REFERENCE.md](./PM_DASHBOARD_API_REFERENCE.md)
85
+ - Understand data availability
86
+ - Review filtering options
87
+ - Note computed fields
88
+
89
+ ### For Project Managers
90
+
91
+ 1. **Review Quick Reference** - [QUICK_REFERENCE.md](./QUICK_REFERENCE.md)
92
+ - Understand dashboard capabilities
93
+ - Review common workflows
94
+ - Provide feedback on priorities
95
+
96
+ ---
97
+
98
+ ## 📊 Dashboard Sections
99
+
100
+ ### 1. Today's Overview
101
+ - Open tickets count
102
+ - Active agents count
103
+ - Overdue tickets alert
104
+ - Pending expenses count
105
+
106
+ ### 2. Financial Snapshot
107
+ - Cash position
108
+ - Pending expenses
109
+ - Unpaid invoices
110
+ - Payroll obligations
111
+
112
+ ### 3. Quick Actions
113
+ - Assign tickets
114
+ - Approve expenses
115
+ - Add inventory
116
+ - Generate payroll
117
+ - Create invoices
118
+ - Add users
119
+
120
+ ### 4. Pending Sales Orders
121
+ - List of orders awaiting conversion
122
+ - Inline actions (assign region, convert to ticket)
123
+ - Bulk conversion capability
124
+
125
+ ### 5. Active Tickets Map
126
+ - Geographic visualization
127
+ - Real-time agent locations
128
+ - Journey tracking
129
+ - Multi-layer filtering
130
+
131
+ ### 6. Inventory Status
132
+ - Stock levels by equipment type
133
+ - Low stock alerts
134
+ - Distribution management
135
+
136
+ ### 7. Pending Approvals
137
+ - Expenses awaiting approval
138
+ - Payroll pending review
139
+ - Draft invoices
140
+
141
+ ### 8. Team Status
142
+ - Agent availability
143
+ - Current assignments
144
+ - Location tracking
145
+
146
+ ---
147
+
148
+ ## 🔑 Key API Endpoints
149
+
150
+ ### Dashboard Stats
151
+ ```
152
+ GET /api/v1/analytics/platform-admin/dashboard
153
+ ```
154
+
155
+ ### Sales Orders
156
+ ```
157
+ GET /api/v1/sales-orders?pending_processing=true
158
+ POST /api/v1/sales-orders/{id}/promote
159
+ ```
160
+
161
+ ### Tickets
162
+ ```
163
+ GET /api/v1/tickets?status=open
164
+ GET /api/v1/tickets/stats
165
+ POST /api/v1/ticket-assignments
166
+ ```
167
+
168
+ ### Expenses
169
+ ```
170
+ GET /api/v1/expenses?approval_status=pending
171
+ POST /api/v1/expenses/{id}/approve
172
+ ```
173
+
174
+ ### Map
175
+ ```
176
+ GET /api/v1/map/entities?project_id={id}
177
+ GET /api/v1/map/journey/{assignment_id}
178
+ ```
179
+
180
+ **See [QUICK_REFERENCE.md](./QUICK_REFERENCE.md) for complete list**
181
+
182
+ ---
183
+
184
+ ## 🎨 Design Principles
185
+
186
+ 1. **Information at a Glance** - Critical metrics visible without scrolling
187
+ 2. **Action-Oriented** - Every metric has a corresponding action button
188
+ 3. **Context-Aware** - Show relevant data based on time, location, status
189
+ 4. **Progressive Disclosure** - Summary → Details ��� Actions
190
+ 5. **Real-Time Updates** - Live data for time-sensitive operations
191
+
192
+ ---
193
+
194
+ ## 🔄 Data Refresh Strategy
195
+
196
+ ### Real-Time (10-30 seconds)
197
+ - Active ticket assignments
198
+ - Agent locations on map
199
+ - Pending approvals count
200
+
201
+ ### Periodic (1-5 minutes)
202
+ - Dashboard statistics
203
+ - Inventory levels
204
+ - Financial metrics
205
+
206
+ ### On-Demand
207
+ - After user actions
208
+ - Manual refresh button
209
+ - Page focus change
210
+
211
+ ---
212
+
213
+ ## 📱 Responsive Design
214
+
215
+ ### Desktop (> 1200px)
216
+ - Full dashboard layout
217
+ - All widgets visible
218
+ - Comfortable map size
219
+
220
+ ### Tablet (768px - 1200px)
221
+ - 2-column layout
222
+ - Stacked widgets
223
+ - Collapsible filters
224
+
225
+ ### Mobile (< 768px)
226
+ - Single column
227
+ - Stacked cards
228
+ - Bottom navigation
229
+ - Map accessible via tab
230
+
231
+ ---
232
+
233
+ ## 🔐 Authentication
234
+
235
+ All API requests require Bearer token authentication:
236
+
237
+ ```
238
+ Authorization: Bearer {access_token}
239
+ ```
240
+
241
+ **Token Refresh:**
242
+ ```
243
+ POST /api/v1/auth/refresh
244
+ Body: { "refresh_token": "your_refresh_token" }
245
+ ```
246
+
247
+ **See API Reference for details**
248
+
249
+ ---
250
+
251
+ ## ⚡ Performance Tips
252
+
253
+ 1. **Lazy load** below-the-fold widgets
254
+ 2. **Debounce** search inputs (300ms)
255
+ 3. **Cache** reference data (roles, statuses, regions)
256
+ 4. **Cluster** map markers when > 50 items
257
+ 5. **Parallel** API calls where possible
258
+ 6. **Skeleton screens** during data fetch
259
+
260
+ ---
261
+
262
+ ## 🧪 Testing Recommendations
263
+
264
+ ### Unit Tests
265
+ - Component rendering
266
+ - User interactions
267
+ - Data transformations
268
+
269
+ ### Integration Tests
270
+ - API call sequences
271
+ - State management
272
+ - Navigation flows
273
+
274
+ ### E2E Tests
275
+ - Critical workflows (assign ticket, approve expense)
276
+ - Cross-browser compatibility
277
+ - Mobile responsiveness
278
+
279
+ ---
280
+
281
+ ## 📋 Implementation Checklist
282
+
283
+ ### Phase 1: Core Dashboard
284
+ - [ ] Dashboard layout structure
285
+ - [ ] Today's overview cards
286
+ - [ ] Financial snapshot widget
287
+ - [ ] Quick actions bar
288
+ - [ ] Authentication integration
289
+
290
+ ### Phase 2: Operations
291
+ - [ ] Pending sales orders widget
292
+ - [ ] Ticket list and assignment
293
+ - [ ] Expense approval workflow
294
+ - [ ] Inventory status widget
295
+
296
+ ### Phase 3: Advanced Features
297
+ - [ ] Interactive map view
298
+ - [ ] Journey tracking
299
+ - [ ] Payroll generation
300
+ - [ ] Invoice management
301
+
302
+ ### Phase 4: Polish
303
+ - [ ] Real-time updates
304
+ - [ ] Responsive design
305
+ - [ ] Error handling
306
+ - [ ] Performance optimization
307
+
308
+ ---
309
+
310
+ ## 🐛 Troubleshooting
311
+
312
+ ### Common Issues
313
+
314
+ **Issue:** API returns 401 Unauthorized
315
+ **Solution:** Check token expiration, refresh if needed
316
+
317
+ **Issue:** Dashboard stats not loading
318
+ **Solution:** Verify user has PM role and project access
319
+
320
+ **Issue:** Map markers not showing
321
+ **Solution:** Check entity_types parameter and data availability
322
+
323
+ **Issue:** Slow performance
324
+ **Solution:** Implement lazy loading, reduce API call frequency
325
+
326
+ ---
327
+
328
+ ## 📞 Support & Resources
329
+
330
+ ### Documentation
331
+ - **API Docs:** `/api/v1/docs` (Swagger UI)
332
+ - **Base URL:** `https://api.swiftops.example.com`
333
+
334
+ ### Team Contacts
335
+ - **Backend Team:** [Contact Info]
336
+ - **Frontend Team:** [Contact Info]
337
+ - **UI/UX Team:** [Contact Info]
338
+ - **Product Manager:** [Contact Info]
339
+
340
+ ### Related Documentation
341
+ - User Role Documentation: `/docs/api/user-profile/APP_MANAGEMENT_SYSTEM.md`
342
+ - Authentication Guide: `/docs/AUTH_API_COMPLETE.md`
343
+ - Finance API: `/docs/FINANCE_MANAGEMENT_IMPLEMENTATION.md`
344
+
345
+ ---
346
+
347
+ ## 🔄 Version History
348
+
349
+ ### Version 1.0 (2025-11-19)
350
+ - Initial documentation release
351
+ - Complete API reference
352
+ - Design guide
353
+ - Quick reference
354
+
355
+ ---
356
+
357
+ ## 📝 Contributing
358
+
359
+ Found an issue or have suggestions?
360
+
361
+ 1. Check existing documentation
362
+ 2. Contact backend team lead
363
+ 3. Submit feedback with specific examples
364
+ 4. Include API endpoint and expected behavior
365
+
366
+ ---
367
+
368
+ ## 📄 License
369
+
370
+ Internal documentation for SwiftOps platform development team.
371
+
372
+ ---
373
+
374
+ **Last Updated:** 2025-11-19
375
+ **Maintained By:** SwiftOps Backend Team
376
+ **Status:** Active Development
docs/hflogs/runtimeerror.txt CHANGED
@@ -1,627 +1,110 @@
1
- ===== Application Startup at 2025-11-18 18:50:31 =====
2
 
3
- INFO: Started server process [7]
4
- INFO: Waiting for application startup.
5
- INFO: 2025-11-18T18:50:43 - app.main: ============================================================
6
- INFO: 2025-11-18T18:50:43 - app.main: 🚀 SwiftOps API v1.0.0 | PRODUCTION
7
- INFO: 2025-11-18T18:50:43 - app.main: ============================================================
8
- INFO: 2025-11-18T18:50:43 - app.main: 📦 Database:
9
- INFO: 2025-11-18T18:50:46 - app.main: ✓ Connected | 42 tables | 13 users
10
- INFO: 2025-11-18T18:50:46 - app.main: 💾 Cache & Sessions:
11
- INFO: 2025-11-18T18:50:47 - app.services.otp_service: ✅ OTP Service initialized with Redis storage
12
- INFO: 2025-11-18T18:50:48 - app.main: ✓ Redis: Connected
13
- INFO: 2025-11-18T18:50:48 - app.main: 🔌 External Services:
14
- INFO: 2025-11-18T18:50:49 - app.main: ✓ Cloudinary: Connected
15
- INFO: 2025-11-18T18:50:49 - app.main: ✓ Resend: Configured
16
- INFO: 2025-11-18T18:50:49 - app.main: ✓ WASender: Connected
17
- INFO: 2025-11-18T18:50:49 - app.main: Supabase: Connected | 6 buckets
18
- INFO: 2025-11-18T18:50:49 - app.main: ============================================================
19
- INFO: 2025-11-18T18:50:49 - app.main: Startup complete | Ready to serve requests
20
- INFO: 2025-11-18T18:50:49 - 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.24.73:60709 - "GET /health HTTP/1.1" 200 OK
24
- INFO: 10.16.42.67:57874 - "GET /health HTTP/1.1" 200 OK
25
- INFO: 10.16.42.67:12808 - "GET /health HTTP/1.1" 200 OK
26
- INFO: 10.16.42.67:12808 - "GET /health HTTP/1.1" 200 OK
27
- INFO: 10.16.4.177:42265 - "GET /health HTTP/1.1" 200 OK
28
- INFO: 10.16.24.73:50145 - "GET /health HTTP/1.1" 200 OK
29
- INFO: 10.16.42.67:6135 - "GET /health HTTP/1.1" 200 OK
30
- INFO: 10.16.4.177:42229 - "GET /health HTTP/1.1" 200 OK
31
- INFO: 10.16.24.73:1989 - "GET /health HTTP/1.1" 200 OK
32
- INFO: 10.16.42.67:50009 - "GET /health HTTP/1.1" 200 OK
33
- INFO: 10.16.42.67:50009 - "GET /health HTTP/1.1" 200 OK
34
- INFO: 10.16.24.73:4083 - "GET /health HTTP/1.1" 200 OK
35
- INFO: 10.16.2.183:3447 - "GET /health HTTP/1.1" 200 OK
36
- INFO: 10.16.2.183:54428 - "GET /health HTTP/1.1" 200 OK
37
- INFO: 10.16.24.73:55483 - "GET /health HTTP/1.1" 200 OK
38
- INFO: 2025-11-18T18:59:30 - app.core.supabase_auth: Session refreshed successfully
39
- INFO: 2025-11-18T18:59:31 - app.api.v1.auth: ✅ Token refreshed successfully for: lewiskimaru01@gmail.com
40
- INFO: 10.16.24.73:31772 - "POST /api/v1/auth/refresh-token HTTP/1.1" 200 OK
41
- ERROR: 2025-11-18T18:59:31 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
42
- WARNING: 2025-11-18T18:59:31 - app.api.deps: Invalid or expired token
43
- INFO: 10.16.2.183:36719 - "GET /api/v1/auth/me HTTP/1.1" 401 Unauthorized
44
- INFO: 10.16.24.73:46966 - "GET /health HTTP/1.1" 200 OK
45
- INFO: 10.16.42.67:1882 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
46
- INFO: 10.16.42.67:28447 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
47
- INFO: 10.16.42.67:23737 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
48
- INFO: 10.16.42.67:1882 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
49
- INFO: 10.16.2.183:51732 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
50
- INFO: 10.16.4.177:51359 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
51
- INFO: 10.16.42.67:1882 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
52
- INFO: 10.16.4.177:51359 - "GET /health HTTP/1.1" 200 OK
53
- INFO: 10.16.42.67:11888 - "GET /health HTTP/1.1" 200 OK
54
- INFO: 10.16.24.73:2931 - "GET /health HTTP/1.1" 200 OK
55
- INFO: 10.16.4.177:4762 - "GET /health HTTP/1.1" 200 OK
56
- INFO: 10.16.42.67:34846 - "GET /health HTTP/1.1" 200 OK
57
- INFO: 10.16.42.67:59242 - "GET /health HTTP/1.1" 200 OK
58
- INFO: 10.16.4.177:43996 - "GET /health HTTP/1.1" 200 OK
59
- INFO: 10.16.4.177:35128 - "GET /health HTTP/1.1" 200 OK
60
- INFO: 10.16.24.73:26057 - "GET /health HTTP/1.1" 200 OK
61
- INFO: 10.16.24.73:23106 - "GET /health HTTP/1.1" 200 OK
62
- INFO: 10.16.24.73:44037 - "GET /health HTTP/1.1" 200 OK
63
- INFO: 10.16.4.177:60432 - "GET /health HTTP/1.1" 200 OK
64
- INFO: 10.16.4.177:46955 - "GET /health HTTP/1.1" 200 OK
65
- INFO: 10.16.24.73:13655 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
66
- INFO: 10.16.4.177:50943 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
67
- INFO: 10.16.2.183:33387 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
68
- INFO: 10.16.4.177:50943 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
69
- INFO: 10.16.2.183:33387 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
70
- INFO: 10.16.42.67:14600 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
71
- INFO: 10.16.42.67:14600 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
72
- INFO: 10.16.2.183:53410 - "GET /health HTTP/1.1" 200 OK
73
- INFO: 10.16.4.177:47228 - "GET /health HTTP/1.1" 200 OK
74
- INFO: 10.16.42.67:10892 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
75
- INFO: 10.16.2.183:11836 - "GET /health HTTP/1.1" 200 OK
76
- INFO: 10.16.4.177:54424 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
77
- INFO: 10.16.42.67:33024 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
78
- INFO: 10.16.42.67:10892 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
79
- INFO: 10.16.2.183:40462 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
80
- INFO: 10.16.4.177:27449 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
81
- INFO: 10.16.24.73:15350 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
82
- INFO: 10.16.4.177:54920 - "GET /health HTTP/1.1" 200 OK
83
- INFO: 10.16.32.101:9894 - "GET /health HTTP/1.1" 200 OK
84
- INFO: 10.16.42.67:47892 - "GET /health HTTP/1.1" 200 OK
85
- INFO: 10.16.2.183:50070 - "GET /health HTTP/1.1" 200 OK
86
- INFO: 10.16.32.101:32108 - "GET /health HTTP/1.1" 200 OK
87
- INFO: 10.16.2.183:62613 - "GET /health HTTP/1.1" 200 OK
88
- INFO: 10.16.32.101:33073 - "GET /health HTTP/1.1" 200 OK
89
- INFO: 10.16.2.183:17374 - "GET /health HTTP/1.1" 200 OK
90
- INFO: 10.16.2.183:39173 - "GET /health HTTP/1.1" 200 OK
91
- INFO: 10.16.2.183:37085 - "GET /health HTTP/1.1" 200 OK
92
- INFO: 10.16.24.73:9390 - "GET /health HTTP/1.1" 200 OK
93
- INFO: 10.16.2.183:55660 - "GET /health HTTP/1.1" 200 OK
94
- INFO: 10.16.2.183:55305 - "GET /health HTTP/1.1" 200 OK
95
- INFO: 10.16.24.73:59709 - "GET /health HTTP/1.1" 200 OK
96
- INFO: 10.16.42.67:28146 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
97
- INFO: 10.16.2.183:8887 - "GET /health HTTP/1.1" 200 OK
98
- INFO: 10.16.32.101:28853 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
99
- INFO: 10.16.32.101:22519 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
100
- INFO: 10.16.24.73:40290 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
101
- INFO: 10.16.2.183:38399 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
102
- INFO: 10.16.4.177:33495 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
103
- INFO: 10.16.2.183:38399 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
104
- INFO: 10.16.24.73:65237 - "GET /health HTTP/1.1" 200 OK
105
- INFO: 2025-11-18T19:09:20 - app.services.audit_service: Audit log created: update on user_preferences by lewiskimaru01@gmail.com
106
- INFO: 2025-11-18T19:09:20 - app.api.v1.auth: Preferences updated for user: lewiskimaru01@gmail.com
107
- INFO: 10.16.4.177:19903 - "PUT /api/v1/auth/me/preferences HTTP/1.1" 200 OK
108
- INFO: 10.16.4.177:1242 - "GET /health HTTP/1.1" 200 OK
109
- INFO: 10.16.4.177:56763 - "GET /health HTTP/1.1" 200 OK
110
- INFO: 10.16.24.73:10443 - "GET /health HTTP/1.1" 200 OK
111
- INFO: 10.16.32.101:21895 - "GET /health HTTP/1.1" 200 OK
112
- INFO: 10.16.42.67:42642 - "GET /health HTTP/1.1" 200 OK
113
- INFO: 10.16.2.183:24496 - "GET /health HTTP/1.1" 200 OK
114
- INFO: 10.16.2.183:3350 - "GET /health HTTP/1.1" 200 OK
115
- INFO: 10.16.4.177:2901 - "GET /health HTTP/1.1" 200 OK
116
- INFO: 10.16.2.183:35947 - "GET /health HTTP/1.1" 200 OK
117
- INFO: 10.16.24.73:34289 - "GET /health HTTP/1.1" 200 OK
118
- INFO: 10.16.2.183:1049 - "GET /health HTTP/1.1" 200 OK
119
- INFO: 10.16.4.177:35653 - "GET /health HTTP/1.1" 200 OK
120
- INFO: 10.16.2.183:51150 - "GET /health HTTP/1.1" 200 OK
121
- INFO: 10.16.4.177:43279 - "GET /health HTTP/1.1" 200 OK
122
- INFO: 10.16.42.67:11310 - "GET /health HTTP/1.1" 200 OK
123
- INFO: 10.16.24.73:35037 - "GET /health HTTP/1.1" 200 OK
124
- INFO: 10.16.24.73:54078 - "GET /health HTTP/1.1" 200 OK
125
- INFO: 10.16.2.183:9083 - "GET /health HTTP/1.1" 200 OK
126
- INFO: 10.16.2.183:45466 - "GET /health HTTP/1.1" 200 OK
127
- INFO: 10.16.2.183:8925 - "GET /health HTTP/1.1" 200 OK
128
- INFO: 10.16.42.67:43405 - "GET /health HTTP/1.1" 200 OK
129
- INFO: 10.16.42.67:26416 - "GET /health HTTP/1.1" 200 OK
130
- INFO: 10.16.24.73:51168 - "GET /health HTTP/1.1" 200 OK
131
- INFO: 10.16.4.177:23684 - "GET /health HTTP/1.1" 200 OK
132
- INFO: 10.16.42.67:45875 - "GET /health HTTP/1.1" 200 OK
133
- INFO: 10.16.42.67:26455 - "GET /health HTTP/1.1" 200 OK
134
- INFO: 10.16.24.73:1362 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
135
- INFO: 10.16.24.73:1362 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
136
- INFO: 10.16.24.73:25500 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
137
- INFO: 10.16.42.67:23487 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
138
- INFO: 10.16.2.183:24873 - "GET /health HTTP/1.1" 200 OK
139
- INFO: 10.16.4.177:28689 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
140
- INFO: 10.16.2.183:28579 - "GET /health HTTP/1.1" 200 OK
141
- INFO: 10.16.42.67:52849 - "GET /health HTTP/1.1" 200 OK
142
- INFO: 10.16.42.67:62755 - "GET /health HTTP/1.1" 200 OK
143
- INFO: 10.16.24.73:28385 - "GET /health HTTP/1.1" 200 OK
144
- INFO: 10.16.42.67:31797 - "GET /health HTTP/1.1" 200 OK
145
- INFO: 10.16.2.183:39394 - "GET /health HTTP/1.1" 200 OK
146
- INFO: 10.16.42.67:24134 - "GET /health HTTP/1.1" 200 OK
147
- INFO: 10.16.24.73:36305 - "GET /health HTTP/1.1" 200 OK
148
- INFO: 10.16.42.67:52657 - "GET /health HTTP/1.1" 200 OK
149
- INFO: 10.16.2.183:20544 - "GET /health HTTP/1.1" 200 OK
150
- INFO: 10.16.2.183:4596 - "GET /health HTTP/1.1" 200 OK
151
- INFO: 10.16.24.73:39932 - "GET /health HTTP/1.1" 200 OK
152
- INFO: 10.16.2.183:33709 - "GET /health HTTP/1.1" 200 OK
153
- INFO: 10.16.4.177:11790 - "GET /health HTTP/1.1" 200 OK
154
- INFO: 10.16.32.101:34312 - "GET /health HTTP/1.1" 200 OK
155
- INFO: 10.16.42.67:1313 - "GET /health HTTP/1.1" 200 OK
156
- INFO: 10.16.24.73:63949 - "GET /health HTTP/1.1" 200 OK
157
- INFO: 10.16.4.177:5892 - "GET /health HTTP/1.1" 200 OK
158
- INFO: 10.16.2.183:25020 - "GET /health HTTP/1.1" 200 OK
159
- INFO: 10.16.2.183:31384 - "GET /health HTTP/1.1" 200 OK
160
- INFO: 10.16.32.101:52843 - "GET /health HTTP/1.1" 200 OK
161
- INFO: 10.16.32.101:52843 - "GET /health HTTP/1.1" 200 OK
162
- INFO: 10.16.32.101:23243 - "GET /health HTTP/1.1" 200 OK
163
- INFO: 10.16.4.177:46110 - "GET /health HTTP/1.1" 200 OK
164
- INFO: 10.16.24.73:4614 - "GET /health HTTP/1.1" 200 OK
165
- INFO: 10.16.24.73:31206 - "GET /health HTTP/1.1" 200 OK
166
- INFO: 10.16.32.101:30230 - "GET /health HTTP/1.1" 200 OK
167
- INFO: 10.16.42.67:53286 - "GET /health HTTP/1.1" 200 OK
168
- INFO: 10.16.4.177:10592 - "GET /health HTTP/1.1" 200 OK
169
- INFO: 10.16.42.67:31196 - "GET /health HTTP/1.1" 200 OK
170
- INFO: 10.16.2.183:30179 - "GET /health HTTP/1.1" 200 OK
171
- INFO: 10.16.4.177:13538 - "GET /health HTTP/1.1" 200 OK
172
- INFO: 10.16.42.67:33157 - "GET /health HTTP/1.1" 200 OK
173
- INFO: 10.16.24.73:46396 - "GET /health HTTP/1.1" 200 OK
174
- INFO: 10.16.2.183:1408 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 403 Forbidden
175
- INFO: 10.16.4.177:56761 - "GET /health HTTP/1.1" 200 OK
176
- INFO: 10.16.4.177:46932 - "GET /health HTTP/1.1" 200 OK
177
- INFO: 10.16.42.67:59371 - "GET /health HTTP/1.1" 200 OK
178
- INFO: 10.16.2.183:24702 - "GET /health HTTP/1.1" 200 OK
179
- INFO: 10.16.42.67:44719 - "GET /health HTTP/1.1" 200 OK
180
- INFO: 10.16.24.73:31374 - "GET /health HTTP/1.1" 200 OK
181
- INFO: 10.16.2.183:21887 - "GET /health HTTP/1.1" 200 OK
182
- INFO: 10.16.24.73:2894 - "GET /health HTTP/1.1" 200 OK
183
- INFO: 10.16.4.177:45637 - "GET /health HTTP/1.1" 200 OK
184
- INFO: 10.16.24.73:28334 - "GET /health HTTP/1.1" 200 OK
185
- INFO: 10.16.24.73:45702 - "GET / HTTP/1.1" 200 OK
186
- INFO: 10.16.42.67:46200 - "GET /health HTTP/1.1" 200 OK
187
- INFO: 10.16.42.67:26422 - "GET /health HTTP/1.1" 200 OK
188
- INFO: 2025-11-18T19:55:46 - app.core.supabase_auth: Session refreshed successfully
189
- INFO: 2025-11-18T19:55:47 - app.api.v1.auth: ✅ Token refreshed successfully for: lewiskimaru01@gmail.com
190
- INFO: 10.16.42.67:42821 - "POST /api/v1/auth/refresh-token HTTP/1.1" 200 OK
191
- INFO: 10.16.42.67:45316 - "GET /health HTTP/1.1" 200 OK
192
- INFO: 10.16.4.177:52344 - "GET /health HTTP/1.1" 200 OK
193
- INFO: 10.16.24.73:26923 - "GET /health HTTP/1.1" 200 OK
194
- INFO: 10.16.2.183:10006 - "GET /health HTTP/1.1" 200 OK
195
- INFO: 10.16.42.67:28896 - "GET /health HTTP/1.1" 200 OK
196
- INFO: 10.16.24.73:11808 - "GET /health HTTP/1.1" 200 OK
197
- INFO: 10.16.4.177:25799 - "GET /health HTTP/1.1" 200 OK
198
- INFO: 10.16.24.73:61041 - "GET /health HTTP/1.1" 200 OK
199
- INFO: 10.16.24.73:3530 - "GET /health HTTP/1.1" 200 OK
200
- INFO: 10.16.4.177:46326 - "GET /health HTTP/1.1" 200 OK
201
- INFO: 10.16.24.73:6918 - "GET /health HTTP/1.1" 200 OK
202
- INFO: 10.16.4.177:35282 - "GET /health HTTP/1.1" 200 OK
203
- INFO: 10.16.4.177:12323 - "GET /health HTTP/1.1" 200 OK
204
- INFO: 10.16.42.67:3473 - "GET /health HTTP/1.1" 200 OK
205
- INFO: 10.16.24.73:36480 - "GET /health HTTP/1.1" 200 OK
206
- INFO: 10.16.2.183:25507 - "GET /health HTTP/1.1" 200 OK
207
- INFO: 10.16.24.73:17019 - "GET /health HTTP/1.1" 200 OK
208
- INFO: 10.16.2.183:25230 - "GET /health HTTP/1.1" 200 OK
209
- INFO: 10.16.42.67:40643 - "GET /health HTTP/1.1" 200 OK
210
- INFO: 10.16.4.177:56906 - "GET /health HTTP/1.1" 200 OK
211
- INFO: 10.16.4.177:43249 - "GET /health HTTP/1.1" 200 OK
212
- INFO: 10.16.24.73:23472 - "GET /health HTTP/1.1" 200 OK
213
- INFO: 10.16.24.73:35057 - "GET /health HTTP/1.1" 200 OK
214
- INFO: 10.16.17.175:56973 - "GET /health HTTP/1.1" 200 OK
215
- ERROR: 2025-11-18T19:56:11 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
216
- WARNING: 2025-11-18T19:56:11 - app.api.deps: Invalid or expired token
217
- ERROR: 2025-11-18T19:56:12 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
218
- WARNING: 2025-11-18T19:56:12 - app.api.deps: Invalid or expired token
219
- INFO: 10.16.42.67:21176 - "GET /api/v1/contractors?skip=0&limit=50 HTTP/1.1" 401 Unauthorized
220
- INFO: 10.16.4.177:10227 - "GET /api/v1/clients?skip=0&limit=50 HTTP/1.1" 401 Unauthorized
221
- INFO: 10.16.4.177:58943 - "GET /health HTTP/1.1" 200 OK
222
- INFO: 10.16.42.67:10300 - "GET /health HTTP/1.1" 200 OK
223
- INFO: 10.16.4.177:58943 - "GET /api/v1/contractors?skip=0&limit=50 HTTP/1.1" 200 OK
224
- INFO: 10.16.4.177:10227 - "GET /api/v1/clients?skip=0&limit=50 HTTP/1.1" 200 OK
225
- INFO: 10.16.2.183:57778 - "GET /health HTTP/1.1" 200 OK
226
- INFO: 10.16.2.183:41718 - "GET /health HTTP/1.1" 200 OK
227
- INFO: 10.16.17.175:58682 - "GET /health HTTP/1.1" 200 OK
228
- INFO: 10.16.24.73:14242 - "GET /health HTTP/1.1" 200 OK
229
- INFO: 10.16.42.67:50622 - "GET /health HTTP/1.1" 200 OK
230
- INFO: 10.16.24.73:32216 - "GET /health HTTP/1.1" 200 OK
231
- INFO: 10.16.42.67:64263 - "GET /health HTTP/1.1" 200 OK
232
- INFO: 10.16.4.177:56807 - "GET /health HTTP/1.1" 200 OK
233
- INFO: 10.16.2.183:65229 - "GET /health HTTP/1.1" 200 OK
234
- INFO: 10.16.2.183:21119 - "GET /health HTTP/1.1" 200 OK
235
- INFO: 10.16.24.73:54186 - "GET /health HTTP/1.1" 200 OK
236
- INFO: 10.16.4.177:9018 - "GET /health HTTP/1.1" 200 OK
237
- INFO: 10.16.42.67:25163 - "GET /health HTTP/1.1" 200 OK
238
- INFO: 10.16.2.183:30343 - "GET /health HTTP/1.1" 200 OK
239
- INFO: 10.16.4.177:53427 - "GET /health HTTP/1.1" 200 OK
240
- INFO: 10.16.4.177:53427 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
241
- INFO: 10.16.4.177:53427 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
242
- INFO: 10.16.17.175:29023 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
243
- INFO: 10.16.4.177:59479 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
244
- INFO: 10.16.17.175:29023 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
245
- INFO: 10.16.4.177:31683 - "GET /health HTTP/1.1" 200 OK
246
- INFO: 10.16.24.73:62343 - "GET /api/v1/users?skip=0&limit=50 HTTP/1.1" 200 OK
247
- INFO: 10.16.4.177:13211 - "GET /api/v1/audit-logs?skip=0&limit=50 HTTP/1.1" 200 OK
248
- INFO: 10.16.2.183:47811 - "GET /health HTTP/1.1" 200 OK
249
- INFO: 10.16.42.67:9644 - "GET /health HTTP/1.1" 200 OK
250
- INFO: 10.16.4.177:45860 - "GET /health HTTP/1.1" 200 OK
251
- INFO: 10.16.42.67:45768 - "GET /health HTTP/1.1" 200 OK
252
- INFO: 10.16.4.177:63910 - "GET /health HTTP/1.1" 200 OK
253
- INFO: 10.16.24.73:28357 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
254
- INFO: 10.16.42.67:1230 - "GET /health HTTP/1.1" 200 OK
255
- INFO: 10.16.4.177:21445 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
256
- INFO: 10.16.24.73:50132 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
257
- INFO: 10.16.42.67:1230 - "GET /api/v1/audit-logs?skip=0&limit=50 HTTP/1.1" 200 OK
258
- INFO: 10.16.4.177:43720 - "GET /health HTTP/1.1" 200 OK
259
- INFO: 10.16.4.177:56844 - "GET /health HTTP/1.1" 200 OK
260
- INFO: 10.16.4.177:3583 - "GET /health HTTP/1.1" 200 OK
261
- INFO: 10.16.24.73:10758 - "GET /health HTTP/1.1" 200 OK
262
- INFO: 10.16.4.177:59687 - "GET /health HTTP/1.1" 200 OK
263
- INFO: 10.16.24.73:10221 - "GET /health HTTP/1.1" 200 OK
264
- INFO: 10.16.24.73:50998 - "GET /health HTTP/1.1" 200 OK
265
- INFO: 10.16.4.177:13202 - "GET /health HTTP/1.1" 200 OK
266
- INFO: 10.16.2.183:31672 - "GET /health HTTP/1.1" 200 OK
267
- INFO: 10.16.17.175:20301 - "GET /health HTTP/1.1" 200 OK
268
- INFO: 10.16.4.177:13530 - "GET /health HTTP/1.1" 200 OK
269
- INFO: 10.16.2.183:46734 - "GET /health HTTP/1.1" 200 OK
270
- INFO: 10.16.4.177:24139 - "GET /health HTTP/1.1" 200 OK
271
- INFO: 10.16.17.175:36330 - "GET /health HTTP/1.1" 200 OK
272
- INFO: 10.16.2.183:1526 - "GET /health HTTP/1.1" 200 OK
273
- INFO: 10.16.4.177:46414 - "GET /health HTTP/1.1" 200 OK
274
- INFO: 10.16.42.67:42359 - "GET /health HTTP/1.1" 200 OK
275
- INFO: 10.16.42.67:27906 - "GET /health HTTP/1.1" 200 OK
276
- INFO: 10.16.42.67:15813 - "GET /health HTTP/1.1" 200 OK
277
- INFO: 10.16.42.67:46955 - "GET /health HTTP/1.1" 200 OK
278
- INFO: 10.16.42.67:65132 - "GET /health HTTP/1.1" 200 OK
279
- INFO: 10.16.42.67:31438 - "GET /health HTTP/1.1" 200 OK
280
- INFO: 10.16.42.67:30436 - "GET /health HTTP/1.1" 200 OK
281
- INFO: 10.16.2.183:33655 - "GET /health HTTP/1.1" 200 OK
282
- INFO: 10.16.42.67:63505 - "GET /health HTTP/1.1" 200 OK
283
- INFO: 10.16.42.67:31088 - "GET /health HTTP/1.1" 200 OK
284
- INFO: 10.16.2.183:38008 - "GET /api/v1/contractors?skip=0&limit=50 HTTP/1.1" 200 OK
285
- INFO: 10.16.4.177:62441 - "GET /api/v1/clients?skip=0&limit=50 HTTP/1.1" 200 OK
286
- INFO: 10.16.17.175:36193 - "GET /health HTTP/1.1" 200 OK
287
- INFO: 10.16.17.175:44411 - "GET /api/v1/users?skip=0&limit=50 HTTP/1.1" 200 OK
288
- INFO: 10.16.2.183:29830 - "GET /health HTTP/1.1" 200 OK
289
- INFO: 10.16.2.183:60280 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
290
- INFO: 10.16.24.73:28744 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
291
- INFO: 10.16.4.177:29046 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
292
- INFO: 10.16.2.183:60280 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
293
- INFO: 10.16.2.183:54610 - "GET /health HTTP/1.1" 200 OK
294
- INFO: 10.16.24.73:13586 - "GET /health HTTP/1.1" 200 OK
295
- INFO: 10.16.2.183:55737 - "GET /health HTTP/1.1" 200 OK
296
- INFO: 10.16.24.73:63158 - "GET /health HTTP/1.1" 200 OK
297
- INFO: 10.16.4.177:13754 - "GET /health HTTP/1.1" 200 OK
298
- INFO: 10.16.24.73:30613 - "GET /health HTTP/1.1" 200 OK
299
- INFO: 10.16.4.177:29811 - "GET /health HTTP/1.1" 200 OK
300
- INFO: 10.16.2.183:33733 - "GET /health HTTP/1.1" 200 OK
301
- INFO: 10.16.2.183:33983 - "GET /health HTTP/1.1" 200 OK
302
- INFO: 10.16.24.73:22716 - "GET /health HTTP/1.1" 200 OK
303
- INFO: 10.16.2.183:42607 - "GET /health HTTP/1.1" 200 OK
304
- INFO: 10.16.2.183:28296 - "GET /health HTTP/1.1" 200 OK
305
- INFO: 10.16.42.67:2829 - "GET /health HTTP/1.1" 200 OK
306
- INFO: 10.16.24.73:45531 - "GET /health HTTP/1.1" 200 OK
307
- INFO: 10.16.42.67:44633 - "GET /health HTTP/1.1" 200 OK
308
- INFO: 10.16.24.73:47194 - "GET /health HTTP/1.1" 200 OK
309
- INFO: 2025-11-18T20:23:08 - app.core.supabase_auth: User signed in successfully: lewiskimaru01@gmail.com
310
- INFO: 2025-11-18T20:23:10 - app.services.audit_service: Audit log created: login on auth by lewiskimaru01@gmail.com
311
- INFO: 2025-11-18T20:23:10 - app.api.v1.auth: User logged in successfully: lewiskimaru01@gmail.com
312
- INFO: 10.16.42.67:36053 - "POST /api/v1/auth/login HTTP/1.1" 200 OK
313
- INFO: 10.16.2.183:50123 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
314
- INFO: 10.16.2.183:50123 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
315
- INFO: 10.16.4.177:35016 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
316
- INFO: 10.16.4.177:50387 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
317
- INFO: 10.16.4.177:50387 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
318
- INFO: 10.16.24.73:39787 - "GET /health HTTP/1.1" 200 OK
319
- INFO: 10.16.42.67:7567 - "GET /health HTTP/1.1" 200 OK
320
- INFO: 10.16.42.67:38182 - "GET /health HTTP/1.1" 200 OK
321
- INFO: 10.16.2.183:18679 - "GET /health HTTP/1.1" 200 OK
322
- INFO: 10.16.42.67:25826 - "GET /health HTTP/1.1" 200 OK
323
- INFO: 10.16.42.67:38562 - "GET /health HTTP/1.1" 200 OK
324
- INFO: 10.16.24.73:40955 - "GET /health HTTP/1.1" 200 OK
325
- INFO: 10.16.2.183:7240 - "GET /health HTTP/1.1" 200 OK
326
- INFO: 10.16.4.177:1198 - "GET /health HTTP/1.1" 200 OK
327
- INFO: 10.16.4.177:26804 - "GET /health HTTP/1.1" 200 OK
328
- INFO: 10.16.24.73:25835 - "GET /health HTTP/1.1" 200 OK
329
- INFO: 10.16.24.73:58339 - "GET /health HTTP/1.1" 200 OK
330
- INFO: 10.16.4.177:4533 - "GET /health HTTP/1.1" 200 OK
331
- INFO: 10.16.24.73:61483 - "GET /health HTTP/1.1" 200 OK
332
- INFO: 10.16.4.177:20828 - "GET /health HTTP/1.1" 200 OK
333
- INFO: 10.16.24.73:58786 - "GET /health HTTP/1.1" 200 OK
334
- INFO: 10.16.2.183:18946 - "GET /health HTTP/1.1" 200 OK
335
- INFO: 10.16.24.73:35647 - "GET /health HTTP/1.1" 200 OK
336
- INFO: 10.16.2.183:1081 - "GET /health HTTP/1.1" 200 OK
337
- INFO: 10.16.4.177:52734 - "GET /health HTTP/1.1" 200 OK
338
- INFO: 10.16.24.73:2465 - "GET /health HTTP/1.1" 200 OK
339
- INFO: 10.16.42.67:59547 - "GET /health HTTP/1.1" 200 OK
340
- INFO: 10.16.42.67:14987 - "GET /health HTTP/1.1" 200 OK
341
- INFO: 10.16.2.183:8051 - "GET /health HTTP/1.1" 200 OK
342
- INFO: 10.16.2.183:52270 - "GET /health HTTP/1.1" 200 OK
343
- INFO: 10.16.2.183:52799 - "GET /health HTTP/1.1" 200 OK
344
- INFO: 10.16.42.67:23702 - "GET /health HTTP/1.1" 200 OK
345
- INFO: 10.16.24.73:24357 - "GET /health HTTP/1.1" 200 OK
346
- INFO: 10.16.42.67:58261 - "GET /health HTTP/1.1" 200 OK
347
- INFO: 10.16.24.73:51569 - "GET /health HTTP/1.1" 200 OK
348
- INFO: 10.16.24.73:32527 - "GET /health HTTP/1.1" 200 OK
349
- INFO: 10.16.2.183:1599 - "GET /health HTTP/1.1" 200 OK
350
- INFO: 10.16.24.73:12838 - "GET /health HTTP/1.1" 200 OK
351
- INFO: 10.16.2.183:15752 - "GET /health HTTP/1.1" 200 OK
352
- INFO: 10.16.2.183:36166 - "GET /health HTTP/1.1" 200 OK
353
- INFO: 10.16.24.73:39485 - "GET /health HTTP/1.1" 200 OK
354
- INFO: 10.16.4.177:65051 - "GET /health HTTP/1.1" 200 OK
355
- INFO: 10.16.2.183:34587 - "GET /health HTTP/1.1" 200 OK
356
- INFO: 10.16.2.183:13415 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
357
- INFO: 10.16.42.67:3804 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
358
- INFO: 10.16.4.177:9240 - "GET /health HTTP/1.1" 200 OK
359
- INFO: 10.16.2.183:50707 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
360
- INFO: 10.16.2.183:13415 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
361
- INFO: 10.16.4.177:26930 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
362
- INFO: 10.16.42.67:3804 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
363
- INFO: 10.16.2.183:13415 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
364
- INFO: 10.16.24.73:3887 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
365
- INFO: 10.16.2.183:50707 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
366
- INFO: 10.16.42.67:3804 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
367
- INFO: 10.16.2.183:13415 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
368
- INFO: 10.16.24.73:3887 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
369
- INFO: 10.16.2.183:50707 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
370
- INFO: 10.16.2.183:50707 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
371
- INFO: 10.16.2.183:45066 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
372
- INFO: 10.16.24.73:51559 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
373
- INFO: 10.16.2.183:50707 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
374
- INFO: 10.16.42.67:46099 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
375
- INFO: 10.16.2.183:45066 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
376
- INFO: 10.16.42.67:47734 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
377
- INFO: 10.16.42.67:46099 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
378
- INFO: 10.16.42.67:2643 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
379
- INFO: 10.16.24.73:56243 - "GET /health HTTP/1.1" 200 OK
380
- INFO: 10.16.42.67:8311 - "GET /health HTTP/1.1" 200 OK
381
- INFO: 10.16.42.67:41171 - "GET /health HTTP/1.1" 200 OK
382
- INFO: 10.16.24.73:5179 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
383
- INFO: 10.16.42.67:49760 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
384
- INFO: 10.16.4.177:4968 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
385
- INFO: 10.16.4.177:6371 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
386
- INFO: 10.16.24.73:63807 - "GET /health HTTP/1.1" 200 OK
387
- INFO: 10.16.24.73:7825 - "GET /health HTTP/1.1" 200 OK
388
- INFO: 10.16.42.67:41712 - "GET /health HTTP/1.1" 200 OK
389
- INFO: 10.16.24.73:59247 - "GET /health HTTP/1.1" 200 OK
390
- INFO: 10.16.4.177:8578 - "GET /health HTTP/1.1" 200 OK
391
- INFO: 10.16.4.177:15840 - "GET /health HTTP/1.1" 200 OK
392
- INFO: 10.16.2.183:55237 - "GET /health HTTP/1.1" 200 OK
393
- INFO: 10.16.2.183:1281 - "GET /health HTTP/1.1" 200 OK
394
- INFO: 10.16.4.177:55913 - "GET /health HTTP/1.1" 200 OK
395
- INFO: 10.16.4.177:23927 - "GET /health HTTP/1.1" 200 OK
396
- INFO: 10.16.2.183:39887 - "GET /health HTTP/1.1" 200 OK
397
- INFO: 10.16.42.67:47296 - "GET /health HTTP/1.1" 200 OK
398
- ERROR: 2025-11-18T20:57:44 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
399
- WARNING: 2025-11-18T20:57:44 - app.api.deps: Invalid or expired token
400
- INFO: 10.16.42.67:18104 - "GET /health HTTP/1.1" 200 OK
401
- INFO: 10.16.24.73:54913 - "GET /health HTTP/1.1" 200 OK
402
- INFO: 10.16.2.183:52230 - "GET /health HTTP/1.1" 200 OK
403
- INFO: 10.16.24.73:15341 - "GET /health HTTP/1.1" 200 OK
404
- INFO: 10.16.24.73:62813 - "GET /health HTTP/1.1" 200 OK
405
- INFO: 10.16.2.183:54376 - "GET /health HTTP/1.1" 200 OK
406
- INFO: 10.16.2.183:25092 - "GET /health HTTP/1.1" 200 OK
407
- INFO: 10.16.2.183:2732 - "GET /health HTTP/1.1" 200 OK
408
- INFO: 10.16.4.177:54053 - "GET /health HTTP/1.1" 200 OK
409
- INFO: 10.16.42.67:1458 - "GET /health HTTP/1.1" 200 OK
410
- INFO: 10.16.2.183:1970 - "GET /health HTTP/1.1" 200 OK
411
- INFO: 10.16.2.183:39171 - "GET /health HTTP/1.1" 200 OK
412
- INFO: 10.16.2.183:31631 - "GET /health HTTP/1.1" 200 OK
413
- INFO: 2025-11-18T20:57:58 - app.core.supabase_auth: Session refreshed successfully
414
- INFO: 2025-11-18T20:57:58 - app.api.v1.auth: ✅ Token refreshed successfully for: lewiskimaru01@gmail.com
415
- INFO: 10.16.2.183:46306 - "GET /health HTTP/1.1" 200 OK
416
- INFO: 10.16.2.183:57772 - "GET /health HTTP/1.1" 200 OK
417
- INFO: 10.16.2.183:16281 - "GET /health HTTP/1.1" 200 OK
418
- INFO: 10.16.42.67:28690 - "GET /health HTTP/1.1" 200 OK
419
- INFO: 10.16.24.73:61506 - "GET /health HTTP/1.1" 200 OK
420
- INFO: 10.16.32.101:49923 - "GET /health HTTP/1.1" 200 OK
421
- INFO: 10.16.42.67:54183 - "GET /health HTTP/1.1" 200 OK
422
- INFO: 10.16.42.67:54878 - "GET /health HTTP/1.1" 200 OK
423
- INFO: 10.16.42.67:7134 - "GET /health HTTP/1.1" 200 OK
424
- INFO: 10.16.32.101:26991 - "GET /health HTTP/1.1" 200 OK
425
- INFO: 10.16.32.101:35984 - "GET /health HTTP/1.1" 200 OK
426
- INFO: 10.16.24.73:23627 - "GET /health HTTP/1.1" 200 OK
427
- INFO: 10.16.2.183:60025 - "GET /health HTTP/1.1" 200 OK
428
- INFO: 10.16.32.101:21380 - "GET /health HTTP/1.1" 200 OK
429
- INFO: 10.16.42.67:7066 - "GET /health HTTP/1.1" 200 OK
430
- INFO: 10.16.2.183:19222 - "GET /health HTTP/1.1" 200 OK
431
- INFO: 10.16.32.101:39468 - "GET /health HTTP/1.1" 200 OK
432
- INFO: 10.16.2.183:38508 - "GET /health HTTP/1.1" 200 OK
433
- INFO: 10.16.4.177:36127 - "GET /health HTTP/1.1" 200 OK
434
- INFO: 10.16.24.73:47417 - "GET /health HTTP/1.1" 200 OK
435
- INFO: 10.16.2.183:48815 - "GET /health HTTP/1.1" 200 OK
436
- INFO: 10.16.4.177:47884 - "GET /health HTTP/1.1" 200 OK
437
- INFO: 10.16.24.73:6357 - "GET /health HTTP/1.1" 200 OK
438
- INFO: 10.16.32.101:3181 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
439
- INFO: 10.16.2.183:21053 - "GET /health HTTP/1.1" 200 OK
440
- INFO: 10.16.24.73:25442 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
441
- INFO: 10.16.2.183:28211 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
442
- INFO: 10.16.32.101:3181 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
443
- INFO: 10.16.2.183:21053 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
444
- INFO: 10.16.24.73:46513 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
445
- INFO: 10.16.4.177:26166 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
446
- INFO: 10.16.42.67:26501 - "GET /health HTTP/1.1" 200 OK
447
- INFO: 10.16.42.67:58512 - "GET /health HTTP/1.1" 200 OK
448
- INFO: 10.16.2.183:22407 - "GET /health HTTP/1.1" 200 OK
449
- INFO: 10.16.2.183:17473 - "GET /health HTTP/1.1" 200 OK
450
- INFO: 2025-11-18T20:59:43 - app.core.supabase_auth: User signed in successfully: lewiskimaru01@gmail.com
451
- INFO: 2025-11-18T20:59:45 - app.services.audit_service: Audit log created: login on auth by lewiskimaru01@gmail.com
452
- INFO: 2025-11-18T20:59:45 - app.api.v1.auth: User logged in successfully: lewiskimaru01@gmail.com
453
- INFO: 10.16.42.67:33772 - "POST /api/v1/auth/login HTTP/1.1" 200 OK
454
- INFO: 10.16.42.67:33772 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
455
- INFO: 10.16.42.67:33772 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
456
- INFO: 10.16.24.73:8023 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
457
- INFO: 10.16.4.177:35710 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
458
- INFO: 10.16.42.67:33772 - "GET /health HTTP/1.1" 200 OK
459
- INFO: 10.16.42.67:32061 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
460
- INFO: 10.16.24.73:12751 - "GET /health HTTP/1.1" 200 OK
461
- INFO: 10.16.24.73:39562 - "GET /health HTTP/1.1" 200 OK
462
- INFO: 10.16.2.183:28946 - "GET /health HTTP/1.1" 200 OK
463
- INFO: 10.16.24.73:61189 - "GET /health HTTP/1.1" 200 OK
464
- INFO: 10.16.4.177:1872 - "GET /health HTTP/1.1" 200 OK
465
- INFO: 10.16.42.67:2928 - "GET /health HTTP/1.1" 200 OK
466
- INFO: 10.16.24.73:6668 - "GET /health HTTP/1.1" 200 OK
467
- INFO: 10.16.2.183:9599 - "GET /health HTTP/1.1" 200 OK
468
- INFO: 10.16.42.67:17623 - "GET /health HTTP/1.1" 200 OK
469
- INFO: 10.16.42.67:14762 - "GET /health HTTP/1.1" 200 OK
470
- INFO: 10.16.24.73:43216 - "GET /health HTTP/1.1" 200 OK
471
- INFO: 10.16.42.67:17685 - "GET /health HTTP/1.1" 200 OK
472
- INFO: 10.16.24.73:48382 - "GET /health HTTP/1.1" 200 OK
473
- INFO: 10.16.4.177:2652 - "GET /health HTTP/1.1" 200 OK
474
- INFO: 10.16.24.73:53262 - "GET /health HTTP/1.1" 200 OK
475
- INFO: 10.16.42.67:47692 - "GET /health HTTP/1.1" 200 OK
476
- INFO: 10.16.4.177:64326 - "GET /health HTTP/1.1" 200 OK
477
- INFO: 10.16.42.67:7307 - "GET /health HTTP/1.1" 200 OK
478
- INFO: 10.16.2.183:25534 - "GET /health HTTP/1.1" 200 OK
479
- INFO: 10.16.42.67:52068 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
480
- INFO: 10.16.2.183:19931 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
481
- INFO: 10.16.4.177:4433 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
482
- INFO: 10.16.42.67:52068 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
483
- INFO: 10.16.2.183:25534 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
484
- INFO: 10.16.4.177:4433 - "GET /health HTTP/1.1" 200 OK
485
- INFO: 10.16.4.177:37222 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
486
- INFO: 10.16.42.67:12340 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
487
- INFO: 10.16.2.183:17646 - "GET /health HTTP/1.1" 200 OK
488
- INFO: 10.16.4.177:56071 - "GET /health HTTP/1.1" 200 OK
489
- INFO: 10.16.24.73:3415 - "GET /health HTTP/1.1" 200 OK
490
- INFO: 10.16.2.183:49486 - "GET /health HTTP/1.1" 200 OK
491
- INFO: 10.16.2.183:49486 - "GET /health HTTP/1.1" 200 OK
492
- INFO: 10.16.42.67:2060 - "GET /health HTTP/1.1" 200 OK
493
- INFO: 10.16.4.177:63825 - "GET /health HTTP/1.1" 200 OK
494
- INFO: 10.16.4.177:37926 - "GET /health HTTP/1.1" 200 OK
495
- INFO: 10.16.24.73:28604 - "GET /health HTTP/1.1" 200 OK
496
- ERROR: 2025-11-19T04:37:19 - app.core.supabase_auth: Session refresh error: Invalid Refresh Token: Already Used
497
- ERROR: 2025-11-19T04:37:19 - app.api.v1.auth: ❌ Token refresh error: Invalid Refresh Token: Already Used
498
- ERROR: 2025-11-19T04:37:19 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
499
- WARNING: 2025-11-19T04:37:19 - app.api.deps: Invalid or expired token
500
- ERROR: 2025-11-19T04:37:20 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
501
- WARNING: 2025-11-19T04:37:20 - app.api.deps: Invalid or expired token
502
- ERROR: 2025-11-19T04:37:20 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
503
- WARNING: 2025-11-19T04:37:20 - app.api.deps: Invalid or expired token
504
- INFO: 10.16.24.73:33660 - "POST /api/v1/auth/refresh-token HTTP/1.1" 401 Unauthorized
505
- INFO: 10.16.24.73:34541 - "GET /api/v1/auth/me/preferences HTTP/1.1" 401 Unauthorized
506
- INFO: 10.16.32.101:40596 - "GET /api/v1/auth/me HTTP/1.1" 401 Unauthorized
507
- INFO: 10.16.2.183:34221 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 401 Unauthorized
508
- INFO: 10.16.42.67:8059 - "GET /health HTTP/1.1" 200 OK
509
- INFO: 10.16.2.183:48493 - "GET /health HTTP/1.1" 200 OK
510
- INFO: 10.16.32.101:9358 - "GET /health HTTP/1.1" 200 OK
511
- INFO: 10.16.32.101:9358 - "GET /health HTTP/1.1" 200 OK
512
- INFO: 10.16.2.183:8594 - "GET /health HTTP/1.1" 200 OK
513
- INFO: 10.16.24.73:57651 - "GET /health HTTP/1.1" 200 OK
514
- INFO: 2025-11-19T04:40:11 - app.core.supabase_auth: User signed in successfully: lewiskimaru01@gmail.com
515
- INFO: 2025-11-19T04:40:12 - app.services.audit_service: Audit log created: login on auth by lewiskimaru01@gmail.com
516
- INFO: 2025-11-19T04:40:12 - app.api.v1.auth: User logged in successfully: lewiskimaru01@gmail.com
517
- INFO: 10.16.2.183:6394 - "POST /api/v1/auth/login HTTP/1.1" 200 OK
518
- INFO: 10.16.2.183:6394 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
519
- INFO: 10.16.2.183:6394 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
520
- INFO: 10.16.24.73:42530 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
521
- INFO: 10.16.32.101:33933 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
522
- INFO: 10.16.32.101:33933 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
523
- INFO: 10.16.2.183:26743 - "GET /health HTTP/1.1" 200 OK
524
- INFO: 10.16.24.73:42664 - "GET /health HTTP/1.1" 200 OK
525
- INFO: 10.16.24.73:15309 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
526
- INFO: 10.16.32.101:35036 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
527
- INFO: 10.16.2.183:43122 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
528
- INFO: 10.16.2.183:16243 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
529
- INFO: 10.16.32.101:52836 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
530
- INFO: 10.16.42.67:1154 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
531
- INFO: 10.16.24.73:12930 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
532
- INFO: 10.16.32.101:58437 - "GET /health HTTP/1.1" 200 OK
533
- INFO: 2025-11-19T04:42:58 - app.core.supabase_auth: Session refreshed successfully
534
- INFO: 2025-11-19T04:42:59 - app.api.v1.auth: ✅ Token refreshed successfully for: lewiskimaru01@gmail.com
535
- INFO: 10.16.29.62:60594 - "POST /api/v1/auth/refresh-token HTTP/1.1" 200 OK
536
- ERROR: 2025-11-19T04:42:59 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
537
- WARNING: 2025-11-19T04:42:59 - app.api.deps: Invalid or expired token
538
- ERROR: 2025-11-19T04:42:59 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
539
- WARNING: 2025-11-19T04:42:59 - app.api.deps: Invalid or expired token
540
- ERROR: 2025-11-19T04:42:59 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
541
- WARNING: 2025-11-19T04:42:59 - app.api.deps: Invalid or expired token
542
- INFO: 10.16.2.183:39737 - "GET /api/v1/auth/me/preferences HTTP/1.1" 401 Unauthorized
543
- INFO: 10.16.24.73:1491 - "GET /api/v1/auth/me HTTP/1.1" 401 Unauthorized
544
- INFO: 10.16.29.62:12374 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 401 Unauthorized
545
- INFO: 10.16.24.73:1491 - "GET /health HTTP/1.1" 200 OK
546
- INFO: 2025-11-19T04:43:30 - app.core.supabase_auth: User signed in successfully: lewiskimaru01@gmail.com
547
- INFO: 2025-11-19T04:43:32 - app.services.audit_service: Audit log created: login on auth by lewiskimaru01@gmail.com
548
- INFO: 2025-11-19T04:43:32 - app.api.v1.auth: User logged in successfully: lewiskimaru01@gmail.com
549
- INFO: 10.16.2.183:44311 - "POST /api/v1/auth/login HTTP/1.1" 200 OK
550
- INFO: 10.16.24.73:33537 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
551
- INFO: 10.16.24.73:33537 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
552
- INFO: 10.16.29.62:37849 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
553
- INFO: 10.16.32.101:29195 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
554
- INFO: 10.16.32.101:29195 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
555
- INFO: 10.16.32.101:28157 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
556
- INFO: 10.16.32.101:30477 - "GET /health HTTP/1.1" 200 OK
557
- INFO: 10.16.29.62:51264 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
558
- INFO: 10.16.32.101:32205 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
559
- INFO: 10.16.29.62:17615 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
560
- INFO: 10.16.42.67:6702 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
561
- INFO: 10.16.42.67:4910 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
562
- INFO: 10.16.42.67:4910 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
563
- INFO: 10.16.42.67:44047 - "GET /api/v1/clients?skip=0&limit=50 HTTP/1.1" 200 OK
564
- INFO: 10.16.24.73:16591 - "GET /api/v1/contractors?skip=0&limit=50 HTTP/1.1" 200 OK
565
- INFO: 10.16.32.101:58521 - "GET /health HTTP/1.1" 200 OK
566
- INFO: 10.16.24.73:34404 - "GET /api/v1/users?skip=0&limit=50 HTTP/1.1" 200 OK
567
- INFO: 10.16.24.73:44278 - "GET /api/v1/audit-logs?skip=0&limit=50 HTTP/1.1" 200 OK
568
- INFO: 10.16.42.67:50328 - "GET /health HTTP/1.1" 200 OK
569
- INFO: 10.16.42.67:10442 - "GET /health HTTP/1.1" 200 OK
570
- INFO: 10.16.29.62:10878 - "GET /api/v1/auth/me/preferences HTTP/1.1" 200 OK
571
- INFO: 10.16.32.101:46692 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
572
- INFO: 10.16.2.183:1137 - "GET /health HTTP/1.1" 200 OK
573
- INFO: 10.16.32.101:25681 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 200 OK
574
- INFO: 10.16.24.73:64236 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
575
- INFO: 10.16.2.183:39926 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
576
- INFO: 10.16.24.73:39456 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
577
- INFO: 10.16.2.183:39926 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
578
- INFO: 10.16.32.101:60235 - "GET /health HTTP/1.1" 200 OK
579
- INFO: 10.16.32.101:11361 - "GET /health HTTP/1.1" 200 OK
580
- INFO: 10.16.32.101:22289 - "GET /health HTTP/1.1" 200 OK
581
- INFO: 10.16.24.73:14015 - "GET /health HTTP/1.1" 200 OK
582
- INFO: 10.16.42.67:18436 - "GET /health HTTP/1.1" 200 OK
583
- INFO: 10.16.32.101:55877 - "GET /health HTTP/1.1" 200 OK
584
- INFO: 10.16.24.73:52870 - "GET /health HTTP/1.1" 200 OK
585
- INFO: 2025-11-19T05:10:14 - app.core.supabase_auth: Session refreshed successfully
586
- INFO: 2025-11-19T05:10:16 - app.api.v1.auth: ✅ Token refreshed successfully for: kamirujoel2000@gmail.com
587
- INFO: 10.16.42.67:60173 - "POST /api/v1/auth/refresh-token HTTP/1.1" 200 OK
588
- ERROR: 2025-11-19T05:10:16 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
589
- WARNING: 2025-11-19T05:10:16 - app.api.deps: Invalid or expired token
590
- ERROR: 2025-11-19T05:10:16 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
591
- WARNING: 2025-11-19T05:10:16 - app.api.deps: Invalid or expired token
592
- ERROR: 2025-11-19T05:10:17 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
593
- WARNING: 2025-11-19T05:10:17 - app.api.deps: Invalid or expired token
594
- INFO: 10.16.24.73:7288 - "GET /api/v1/auth/me HTTP/1.1" 401 Unauthorized
595
- ERROR: 2025-11-19T05:10:17 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
596
- WARNING: 2025-11-19T05:10:17 - app.api.deps: Invalid or expired token
597
- INFO: 10.16.2.183:16465 - "GET /api/v1/clients?skip=0&limit=100 HTTP/1.1" 401 Unauthorized
598
- INFO: 10.16.2.183:62132 - "GET /api/v1/users?skip=0&limit=100 HTTP/1.1" 401 Unauthorized
599
- INFO: 10.16.2.183:47393 - "GET /api/v1/contractors?skip=0&limit=100 HTTP/1.1" 401 Unauthorized
600
- INFO: 10.16.42.67:57285 - "GET /health HTTP/1.1" 200 OK
601
- INFO: 2025-11-19T07:30:23 - app.core.supabase_auth: Session refreshed successfully
602
- INFO: 2025-11-19T07:30:25 - app.api.v1.auth: ✅ Token refreshed successfully for: lewiskimaru01@gmail.com
603
- INFO: 10.16.42.67:51262 - "POST /api/v1/auth/refresh-token HTTP/1.1" 200 OK
604
- ERROR: 2025-11-19T07:30:26 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
605
- WARNING: 2025-11-19T07:30:26 - app.api.deps: Invalid or expired token
606
- ERROR: 2025-11-19T07:30:26 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
607
- WARNING: 2025-11-19T07:30:26 - app.api.deps: Invalid or expired token
608
- ERROR: 2025-11-19T07:30:26 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
609
- WARNING: 2025-11-19T07:30:26 - app.api.deps: Invalid or expired token
610
- INFO: 10.16.2.183:13623 - "GET /api/v1/auth/me HTTP/1.1" 401 Unauthorized
611
- INFO: 10.16.32.101:65493 - "GET /api/v1/auth/me/preferences/available-apps HTTP/1.1" 401 Unauthorized
612
- INFO: 10.16.32.101:63769 - "GET /api/v1/auth/me/preferences HTTP/1.1" 401 Unauthorized
613
- INFO: 2025-11-19T07:30:49 - app.core.supabase_auth: User signed in successfully: lewiskimaru01@gmail.com
614
- INFO: 2025-11-19T07:30:52 - app.services.audit_service: Audit log created: login on auth by lewiskimaru01@gmail.com
615
- INFO: 2025-11-19T07:30:52 - app.api.v1.auth: User logged in successfully: lewiskimaru01@gmail.com
616
- INFO: 10.16.2.183:60486 - "POST /api/v1/auth/login HTTP/1.1" 200 OK
617
- INFO: 10.16.24.73:55086 - "GET /api/v1/auth/me HTTP/1.1" 200 OK
618
- INFO: 10.16.32.101:27054 - "GET /api/v1/contractors?skip=0&limit=20 HTTP/1.1" 200 OK
619
- INFO: 10.16.42.67:5575 - "GET /api/v1/clients?skip=0&limit=20 HTTP/1.1" 200 OK
620
- INFO: 10.16.32.101:16146 - "GET /api/v1/users?skip=0&limit=20 HTTP/1.1" 200 OK
621
- INFO: 10.16.2.183:56271 - "GET /api/v1/audit-logs?skip=0&limit=20 HTTP/1.1" 200 OK
622
- INFO: 10.16.32.101:35137 - "GET /health HTTP/1.1" 200 OK
623
- INFO: 10.16.24.73:29699 - "GET /health HTTP/1.1" 200 OK
624
- INFO: 10.16.2.183:8281 - "GET /health HTTP/1.1" 200 OK
625
- INFO: 10.16.2.183:34724 - "GET /health HTTP/1.1" 200 OK
626
- INFO: 10.16.2.183:44681 - "GET /health HTTP/1.1" 200 OK
627
- INFO: 10.16.2.183:43318 - "GET /health HTTP/1.1" 200 OK
 
1
+ ===== Application Startup at 2025-11-19 10:47:20 =====
2
 
3
+ Traceback (most recent call last):
4
+ File "/usr/local/bin/uvicorn", line 8, in <module>
5
+ sys.exit(main())
6
+ ^^^^^^
7
+ File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1485, in __call__
8
+ return self.main(*args, **kwargs)
9
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^
10
+ File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1406, in main
11
+ rv = self.invoke(ctx)
12
+ ^^^^^^^^^^^^^^^^
13
+ File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1269, in invoke
14
+ return ctx.invoke(self.callback, **ctx.params)
15
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16
+ File "/usr/local/lib/python3.11/site-packages/click/core.py", line 824, in invoke
17
+ return callback(*args, **kwargs)
18
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
19
+ File "/usr/local/lib/python3.11/site-packages/uvicorn/main.py", line 416, in main
20
+ run(
21
+ File "/usr/local/lib/python3.11/site-packages/uvicorn/main.py", line 587, in run
22
+ server.run()
23
+ File "/usr/local/lib/python3.11/site-packages/uvicorn/server.py", line 61, in run
24
+ return asyncio.run(self.serve(sockets=sockets))
25
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26
+ File "/usr/local/lib/python3.11/asyncio/runners.py", line 190, in run
27
+ return runner.run(main)
28
+ ^^^^^^^^^^^^^^^^
29
+ File "/usr/local/lib/python3.11/asyncio/runners.py", line 118, in run
30
+ return self._loop.run_until_complete(task)
31
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
32
+ File "uvloop/loop.pyx", line 1518, in uvloop.loop.Loop.run_until_complete
33
+ File "/usr/local/lib/python3.11/site-packages/uvicorn/server.py", line 68, in serve
34
+ config.load()
35
+ File "/usr/local/lib/python3.11/site-packages/uvicorn/config.py", line 467, in load
36
+ self.loaded_app = import_from_string(self.app)
37
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38
+ File "/usr/local/lib/python3.11/site-packages/uvicorn/importer.py", line 21, in import_from_string
39
+ module = importlib.import_module(module_str)
40
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41
+ File "/usr/local/lib/python3.11/importlib/__init__.py", line 126, in import_module
42
+ return _bootstrap._gcd_import(name[level:], package, level)
43
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44
+ File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
45
+ File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
46
+ File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
47
+ File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
48
+ File "<frozen importlib._bootstrap_external>", line 940, in exec_module
49
+ File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
50
+ File "/app/src/app/main.py", line 141, in <module>
51
+ from app.api.v1.router import api_router
52
+ File "/app/src/app/api/v1/router.py", line 5, in <module>
53
+ from app.api.v1 import (
54
+ File "/app/src/app/api/v1/expenses.py", line 18, in <module>
55
+ from app.core.database import get_db
56
+ ImportError: cannot import name 'get_db' from 'app.core.database' (/app/src/app/core/database.py)
57
+ Traceback (most recent call last):
58
+ File "/usr/local/bin/uvicorn", line 8, in <module>
59
+ sys.exit(main())
60
+ ^^^^^^
61
+ File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1485, in __call__
62
+ return self.main(*args, **kwargs)
63
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^
64
+ File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1406, in main
65
+ rv = self.invoke(ctx)
66
+ ^^^^^^^^^^^^^^^^
67
+ File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1269, in invoke
68
+ return ctx.invoke(self.callback, **ctx.params)
69
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
70
+ File "/usr/local/lib/python3.11/site-packages/click/core.py", line 824, in invoke
71
+ return callback(*args, **kwargs)
72
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
73
+ File "/usr/local/lib/python3.11/site-packages/uvicorn/main.py", line 416, in main
74
+ run(
75
+ File "/usr/local/lib/python3.11/site-packages/uvicorn/main.py", line 587, in run
76
+ server.run()
77
+ File "/usr/local/lib/python3.11/site-packages/uvicorn/server.py", line 61, in run
78
+ return asyncio.run(self.serve(sockets=sockets))
79
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
80
+ File "/usr/local/lib/python3.11/asyncio/runners.py", line 190, in run
81
+ return runner.run(main)
82
+ ^^^^^^^^^^^^^^^^
83
+ File "/usr/local/lib/python3.11/asyncio/runners.py", line 118, in run
84
+ return self._loop.run_until_complete(task)
85
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
86
+ File "uvloop/loop.pyx", line 1518, in uvloop.loop.Loop.run_until_complete
87
+ File "/usr/local/lib/python3.11/site-packages/uvicorn/server.py", line 68, in serve
88
+ config.load()
89
+ File "/usr/local/lib/python3.11/site-packages/uvicorn/config.py", line 467, in load
90
+ self.loaded_app = import_from_string(self.app)
91
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
92
+ File "/usr/local/lib/python3.11/site-packages/uvicorn/importer.py", line 21, in import_from_string
93
+ module = importlib.import_module(module_str)
94
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
95
+ File "/usr/local/lib/python3.11/importlib/__init__.py", line 126, in import_module
96
+ return _bootstrap._gcd_import(name[level:], package, level)
97
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
98
+ File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
99
+ File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
100
+ File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
101
+ File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
102
+ File "<frozen importlib._bootstrap_external>", line 940, in exec_module
103
+ File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
104
+ File "/app/src/app/main.py", line 141, in <module>
105
+ from app.api.v1.router import api_router
106
+ File "/app/src/app/api/v1/router.py", line 5, in <module>
107
+ from app.api.v1 import (
108
+ File "/app/src/app/api/v1/expenses.py", line 18, in <module>
109
+ from app.core.database import get_db
110
+ ImportError: cannot import name 'get_db' from 'app.core.database' (/app/src/app/core/database.py)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/app/api/v1/expenses.py CHANGED
@@ -15,8 +15,7 @@ from sqlalchemy.orm import Session
15
  from typing import Optional, List
16
  from uuid import UUID
17
 
18
- from app.core.database import get_db
19
- from app.core.auth import get_current_user
20
  from app.models.user import User
21
  from app.schemas.ticket_expense import (
22
  TicketExpenseCreate,
 
15
  from typing import Optional, List
16
  from uuid import UUID
17
 
18
+ from app.api.deps import get_db, get_current_user
 
19
  from app.models.user import User
20
  from app.schemas.ticket_expense import (
21
  TicketExpenseCreate,
src/app/api/v1/incident_reports.py CHANGED
@@ -13,8 +13,7 @@ from sqlalchemy.orm import Session
13
  from typing import List, Optional
14
  from uuid import UUID
15
 
16
- from app.core.database import get_db
17
- from app.core.auth import get_current_user
18
  from app.models.user import User
19
  from app.schemas.ticket_progress import (
20
  TicketIncidentReportCreate,
 
13
  from typing import List, Optional
14
  from uuid import UUID
15
 
16
+ from app.api.deps import get_db, get_current_user
 
17
  from app.models.user import User
18
  from app.schemas.ticket_progress import (
19
  TicketIncidentReportCreate,
src/app/api/v1/progress_reports.py CHANGED
@@ -14,8 +14,7 @@ from sqlalchemy.orm import Session
14
  from typing import List, Optional
15
  from uuid import UUID
16
 
17
- from app.core.database import get_db
18
- from app.core.auth import get_current_user
19
  from app.models.user import User
20
  from app.schemas.ticket_progress import (
21
  TicketProgressReportCreate,
 
14
  from typing import List, Optional
15
  from uuid import UUID
16
 
17
+ from app.api.deps import get_db, get_current_user
 
18
  from app.models.user import User
19
  from app.schemas.ticket_progress import (
20
  TicketProgressReportCreate,
tests/integration/test_auth_audit_logs.py CHANGED
@@ -18,7 +18,7 @@ from sqlalchemy.orm import Session
18
  from fastapi.testclient import TestClient
19
 
20
  from app.main import app
21
- from app.core.database import get_db
22
  from app.models.user import User
23
  from app.models.audit_log import AuditLog
24
  from app.services.password_reset_service import PasswordResetService
 
18
  from fastapi.testclient import TestClient
19
 
20
  from app.main import app
21
+ from app.api.deps import get_db
22
  from app.models.user import User
23
  from app.models.audit_log import AuditLog
24
  from app.services.password_reset_service import PasswordResetService
tests/integration/test_password_reset.py CHANGED
@@ -16,7 +16,7 @@ from sqlalchemy.orm import Session
16
  from fastapi.testclient import TestClient
17
 
18
  from app.main import app
19
- from app.core.database import get_db
20
  from app.models.user import User
21
  from app.models.invitation import UserInvitation
22
  from app.models.audit_log import AuditLog
 
16
  from fastapi.testclient import TestClient
17
 
18
  from app.main import app
19
+ from app.api.deps import get_db
20
  from app.models.user import User
21
  from app.models.invitation import UserInvitation
22
  from app.models.audit_log import AuditLog