Skip to content

Commit a93dc78

Browse files
committed
Merge branch 'main' of https://github.com/dashdoc/dashmap
2 parents 9dc8f7d + c762829 commit a93dc78

File tree

15 files changed

+172
-116
lines changed

15 files changed

+172
-116
lines changed

backend/API_DOC.md

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ Vehicle routing backend API built with Django. All endpoints return JSON data.
77
http://localhost:8000/api/
88
```
99

10+
## Root Endpoint
11+
**GET** `/`
12+
13+
Basic status endpoint that returns API information.
14+
15+
Response:
16+
```json
17+
{
18+
"status": "ok",
19+
"message": "Welcome to Dashmap!"
20+
}
21+
```
22+
1023
## Authentication
1124
API uses token-based authentication. All endpoints (except login) require a valid authentication token.
1225

@@ -316,7 +329,7 @@ All list endpoints return data in this format:
316329
"contact_phone": "555-0001",
317330
"notes": "Use rear entrance"
318331
},
319-
"order": 1,
332+
"sequence": 1,
320333
"planned_arrival_time": "09:00:00",
321334
"actual_arrival_datetime": null,
322335
"actual_departure_datetime": null,
@@ -352,7 +365,7 @@ Includes all above fields plus:
352365
"contact_phone": "555-0001",
353366
"notes": "Use rear entrance"
354367
},
355-
"order": 1,
368+
"sequence": 1,
356369
"planned_arrival_time": "09:00:00",
357370
"actual_arrival_datetime": null,
358371
"actual_departure_datetime": null,
@@ -402,7 +415,7 @@ Includes all above fields plus:
402415
"longitude": "-87.629799",
403416
"stop_type": "pickup"
404417
},
405-
"order": 1,
418+
"sequence": 1,
406419
"planned_arrival_time": "09:00:00",
407420
"actual_arrival_datetime": null,
408421
"actual_departure_datetime": null,
@@ -424,14 +437,14 @@ The `linked_order` field contains the order that uses this stop as either a pick
424437

425438
The field will be `null` if no order is associated with the stop.
426439

427-
#### Trip Stop Order Management
440+
#### Trip Stop Sequence Management
428441

429-
**Creating Trip Stops with Order Conflicts:**
430-
When creating a trip stop with an order that already exists, the system automatically shifts existing stops to higher order numbers to make room for the new stop.
442+
**Creating Trip Stops with Sequence Conflicts:**
443+
When creating a trip stop with a sequence that already exists, the system automatically shifts existing stops to higher sequence numbers to make room for the new stop.
431444

432-
Example: If a trip has stops with orders [1, 2, 3] and you create a new stop with order=2, the result will be:
433-
- New stop: order=2
434-
- Existing stops: orders [1, 3, 4] (original order=2 and order=3 are shifted up)
445+
Example: If a trip has stops with sequences [1, 2, 3] and you create a new stop with sequence=2, the result will be:
446+
- New stop: sequence=2
447+
- Existing stops: sequences [1, 3, 4] (original sequence=2 and sequence=3 are shifted up)
435448

436449
#### Order Completeness Validation
437450

@@ -463,7 +476,7 @@ Trips must contain complete order journeys (both pickup and delivery stops). Thi
463476
Request:
464477
```json
465478
{
466-
"order": 1,
479+
"sequence": 1,
467480
"pickup_time": "09:00:00",
468481
"delivery_time": "14:00:00",
469482
"notes": "Handle with care"
@@ -476,7 +489,7 @@ Response:
476489
"message": "Successfully added order ORD-2024-0001 to trip",
477490
"pickup_trip_stop": {
478491
"id": 15,
479-
"order": 3,
492+
"sequence": 3,
480493
"planned_arrival_time": "09:00:00",
481494
"stop": {
482495
"id": 10,
@@ -486,7 +499,7 @@ Response:
486499
},
487500
"delivery_trip_stop": {
488501
"id": 16,
489-
"order": 4,
502+
"sequence": 4,
490503
"planned_arrival_time": "14:00:00",
491504
"stop": {
492505
"id": 11,
@@ -498,23 +511,23 @@ Response:
498511
```
499512

500513
**Deleting Trip Stops:**
501-
When a trip stop is deleted, remaining stops with higher order numbers are automatically shifted down to close gaps and maintain consecutive ordering.
514+
When a trip stop is deleted, remaining stops with higher sequence numbers are automatically shifted down to close gaps and maintain consecutive sequencing.
502515

503-
Example: If a trip has stops with orders [1, 2, 3] and you delete the stop with order=2, the result will be:
504-
- Remaining stops: orders [1, 2] (original order=3 is shifted down to order=2)
516+
Example: If a trip has stops with sequences [1, 2, 3] and you delete the stop with sequence=2, the result will be:
517+
- Remaining stops: sequences [1, 2] (original sequence=3 is shifted down to sequence=2)
505518

506519
**Bulk Reordering:**
507-
Use the reorder endpoint to update multiple trip stop orders in a single transaction.
520+
Use the reorder endpoint to update multiple trip stop sequences in a single transaction.
508521

509522
**POST** `/api/trips/{trip_id}/reorder-stops/`
510523

511524
Request:
512525
```json
513526
{
514527
"orders": [
515-
{"id": 10, "order": 1},
516-
{"id": 11, "order": 2},
517-
{"id": 12, "order": 3}
528+
{"id": 10, "sequence": 1},
529+
{"id": 11, "sequence": 2},
530+
{"id": 12, "sequence": 3}
518531
]
519532
}
520533
```
@@ -527,7 +540,7 @@ Response:
527540
"id": 10,
528541
"trip": 5,
529542
"stop": {...},
530-
"order": 1,
543+
"sequence": 1,
531544
"planned_arrival_time": "09:00:00",
532545
"actual_arrival_datetime": null,
533546
"actual_departure_datetime": null,
@@ -538,7 +551,7 @@ Response:
538551
}
539552
```
540553

541-
All trip stop IDs in the request must belong to the specified trip. The response returns all trip stops for the trip in their new order.
554+
All trip stop IDs in the request must belong to the specified trip. The response returns all trip stops for the trip in their new sequence.
542555

543556
## Error Responses
544557

backend/dashmap/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
"""
1717
from django.contrib import admin
1818
from django.urls import path, include
19+
from . import views
1920

2021
urlpatterns = [
22+
path('', views.root_view, name='root'),
2123
path('admin/', admin.site.urls),
2224
path('api/', include('accounts.urls')),
2325
path('api/', include('companies.urls')),

backend/dashmap/views.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from django.http import JsonResponse
2+
3+
4+
def root_view(request):
5+
"""Basic root API endpoint that returns status information."""
6+
return JsonResponse({
7+
"status": "ok",
8+
"message": "Welcome to Dashmap!"
9+
})

backend/trips/admin.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ class StopAdmin(admin.ModelAdmin):
1111
class TripStopInline(admin.TabularInline):
1212
model = TripStop
1313
extra = 0
14-
ordering = ['order']
15-
fields = ['stop', 'order', 'planned_arrival_time', 'is_completed', 'notes']
14+
ordering = ['sequence']
15+
fields = ['stop', 'sequence', 'planned_arrival_time', 'is_completed', 'notes']
1616

1717
@admin.register(Trip)
1818
class TripAdmin(admin.ModelAdmin):
@@ -39,7 +39,7 @@ class TripAdmin(admin.ModelAdmin):
3939

4040
@admin.register(TripStop)
4141
class TripStopAdmin(admin.ModelAdmin):
42-
list_display = ['trip', 'stop', 'order', 'planned_arrival_time', 'is_completed']
42+
list_display = ['trip', 'stop', 'sequence', 'planned_arrival_time', 'is_completed']
4343
search_fields = ['trip__name', 'stop__name']
4444
list_filter = ['is_completed', 'trip__status']
45-
ordering = ['trip', 'order']
45+
ordering = ['trip', 'sequence']

backend/trips/migrations/0002_stop_latitude_stop_longitude.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,23 @@
44

55

66
class Migration(migrations.Migration):
7-
87
dependencies = [
9-
('trips', '0001_initial'),
8+
("trips", "0001_initial"),
109
]
1110

1211
operations = [
1312
migrations.AddField(
14-
model_name='stop',
15-
name='latitude',
16-
field=models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True),
13+
model_name="stop",
14+
name="latitude",
15+
field=models.DecimalField(
16+
blank=True, decimal_places=6, max_digits=9, null=True
17+
),
1718
),
1819
migrations.AddField(
19-
model_name='stop',
20-
name='longitude',
21-
field=models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True),
20+
model_name="stop",
21+
name="longitude",
22+
field=models.DecimalField(
23+
blank=True, decimal_places=6, max_digits=9, null=True
24+
),
2225
),
2326
]

backend/trips/migrations/0003_alter_tripstop_stop_delete_stop.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,22 @@
55

66

77
class Migration(migrations.Migration):
8-
98
dependencies = [
10-
('orders', '0001_initial'),
11-
('trips', '0002_stop_latitude_stop_longitude'),
9+
("orders", "0001_initial"),
10+
("trips", "0002_stop_latitude_stop_longitude"),
1211
]
1312

1413
operations = [
1514
migrations.AlterField(
16-
model_name='tripstop',
17-
name='stop',
18-
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='trip_stops', to='orders.stop'),
15+
model_name="tripstop",
16+
name="stop",
17+
field=models.ForeignKey(
18+
on_delete=django.db.models.deletion.CASCADE,
19+
related_name="trip_stops",
20+
to="orders.stop",
21+
),
1922
),
2023
migrations.DeleteModel(
21-
name='Stop',
24+
name="Stop",
2225
),
2326
]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Generated by Django 5.2.5 on 2025-09-11 09:52
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("trips", "0003_alter_tripstop_stop_delete_stop"),
9+
]
10+
11+
operations = [
12+
migrations.AlterModelOptions(
13+
name="tripstop",
14+
options={"ordering": ["sequence"]},
15+
),
16+
migrations.RenameField(
17+
model_name="tripstop",
18+
old_name="order",
19+
new_name="sequence",
20+
),
21+
migrations.AlterUniqueTogether(
22+
name="tripstop",
23+
unique_together={("trip", "sequence")},
24+
),
25+
]

backend/trips/models.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,16 @@ def __str__(self):
3131
class TripStop(models.Model):
3232
trip = models.ForeignKey(Trip, on_delete=models.CASCADE, related_name='trip_stops')
3333
stop = models.ForeignKey(Stop, on_delete=models.CASCADE, related_name='trip_stops')
34-
order = models.PositiveIntegerField()
34+
sequence = models.PositiveIntegerField()
3535
planned_arrival_time = models.TimeField()
3636
actual_arrival_datetime = models.DateTimeField(null=True, blank=True)
3737
actual_departure_datetime = models.DateTimeField(null=True, blank=True)
3838
notes = models.TextField(blank=True)
3939
is_completed = models.BooleanField(default=False)
4040

4141
class Meta:
42-
ordering = ['order']
43-
unique_together = ['trip', 'order']
42+
ordering = ['sequence']
43+
unique_together = ['trip', 'sequence']
4444

4545
def save(self, *args, skip_validation=False, **kwargs):
4646
# Only validate for new TripStop instances (not updates) and when not explicitly skipped
@@ -50,4 +50,4 @@ def save(self, *args, skip_validation=False, **kwargs):
5050
super().save(*args, **kwargs)
5151

5252
def __str__(self):
53-
return f"{self.trip.name} - Stop {self.order}: {self.stop.name}"
53+
return f"{self.trip.name} - Stop {self.sequence}: {self.stop.name}"

backend/trips/services.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -161,19 +161,19 @@ def add_order_to_trip(trip: Trip, order: Order, pickup_time, delivery_time, note
161161
delivery_stop = order_stops['delivery_stop']
162162

163163
with transaction.atomic():
164-
# Get the next available order numbers for the trip
165-
last_order = trip.trip_stops.aggregate(
166-
max_order=models.Max('order')
167-
)['max_order'] or 0
164+
# Get the next available sequence numbers for the trip
165+
last_sequence = trip.trip_stops.aggregate(
166+
max_sequence=models.Max('sequence')
167+
)['max_sequence'] or 0
168168

169-
pickup_order = last_order + 1
170-
delivery_order = last_order + 2
169+
pickup_sequence = last_sequence + 1
170+
delivery_sequence = last_sequence + 2
171171

172172
# Create both trip stops with validation disabled
173173
pickup_trip_stop = TripStop(
174174
trip=trip,
175175
stop=pickup_stop,
176-
order=pickup_order,
176+
sequence=pickup_sequence,
177177
planned_arrival_time=pickup_time,
178178
notes=notes or f'Pickup for {order.order_number}'
179179
)
@@ -182,7 +182,7 @@ def add_order_to_trip(trip: Trip, order: Order, pickup_time, delivery_time, note
182182
delivery_trip_stop = TripStop(
183183
trip=trip,
184184
stop=delivery_stop,
185-
order=delivery_order,
185+
sequence=delivery_sequence,
186186
planned_arrival_time=delivery_time,
187187
notes=notes or f'Delivery for {order.order_number}'
188188
)
@@ -204,7 +204,7 @@ def validate_pickup_before_delivery(trip: Trip) -> None:
204204
Raises:
205205
TripValidationError: If any order has delivery before pickup
206206
"""
207-
trip_stops = trip.trip_stops.select_related('stop', 'stop__order').order_by('order')
207+
trip_stops = trip.trip_stops.select_related('stop', 'stop__order').order_by('sequence')
208208
orders_in_trip = {}
209209

210210
# Group stops by order and track their positions
@@ -216,16 +216,16 @@ def validate_pickup_before_delivery(trip: Trip) -> None:
216216
orders_in_trip[order.id]['stops'].append({
217217
'trip_stop': trip_stop,
218218
'stop_type': trip_stop.stop.stop_type,
219-
'order_position': trip_stop.order
219+
'sequence_position': trip_stop.sequence
220220
})
221221

222222
# Check each order's pickup-delivery ordering
223223
for order_data in orders_in_trip.values():
224224
order = order_data['order']
225225
stops = order_data['stops']
226226

227-
pickup_positions = [s['order_position'] for s in stops if s['stop_type'] == 'pickup']
228-
delivery_positions = [s['order_position'] for s in stops if s['stop_type'] == 'delivery']
227+
pickup_positions = [s['sequence_position'] for s in stops if s['stop_type'] == 'pickup']
228+
delivery_positions = [s['sequence_position'] for s in stops if s['stop_type'] == 'delivery']
229229

230230
# If both pickup and delivery exist, pickup must come before delivery
231231
if pickup_positions and delivery_positions:

0 commit comments

Comments
 (0)