From 4024f5ed14ba18207a7ce780f742e83c4e5b08dd Mon Sep 17 00:00:00 2001 From: Andrew Yager Date: Sat, 28 Feb 2026 15:17:29 +1100 Subject: [PATCH 1/3] feat: add asset thumbnails to location detail page Prefetch primary images on location detail querysets to avoid N+1 queries, and render thumbnails in both the desktop table view (40x40 column) and mobile card layout (48x48). Matches the existing pattern from the main asset list view. Co-Authored-By: Claude Opus 4.6 --- src/assets/views.py | 34 +++++++++++++++++------ src/templates/assets/location_detail.html | 22 ++++++++++++++- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/assets/views.py b/src/assets/views.py index e190652..5c63733 100644 --- a/src/assets/views.py +++ b/src/assets/views.py @@ -2351,12 +2351,23 @@ def location_detail(request, pk): descendant_ids = [loc.pk for loc in location.get_descendants()] all_location_ids = [location.pk] + descendant_ids + # Prefetch primary image to avoid N+1 queries + primary_image_prefetch = Prefetch( + "images", + queryset=AssetImage.objects.filter(is_primary=True), + to_attr="primary_images", + ) + # Base querysets for three tabs - present_qs = Asset.objects.filter( - current_location_id__in=all_location_ids, - status="active", - checked_out_to__isnull=True, - ).select_related("category", "category__department", "checked_out_to") + present_qs = ( + Asset.objects.filter( + current_location_id__in=all_location_ids, + status="active", + checked_out_to__isnull=True, + ) + .select_related("category", "category__department", "checked_out_to") + .prefetch_related(primary_image_prefetch) + ) # Subquery: due_date from most recent checkout transaction latest_checkout_due = ( @@ -2370,13 +2381,18 @@ def location_detail(request, pk): checked_out_to__isnull=False, ) .select_related("category", "category__department", "checked_out_to") + .prefetch_related(primary_image_prefetch) .annotate(checkout_due_date=Subquery(latest_checkout_due)) ) - draft_qs = Asset.objects.filter( - current_location_id__in=all_location_ids, - status="draft", - ).select_related("category", "category__department", "checked_out_to") + draft_qs = ( + Asset.objects.filter( + current_location_id__in=all_location_ids, + status="draft", + ) + .select_related("category", "category__department", "checked_out_to") + .prefetch_related(primary_image_prefetch) + ) # Tab counts present_count = present_qs.count() diff --git a/src/templates/assets/location_detail.html b/src/templates/assets/location_detail.html index 2215218..f745786 100644 --- a/src/templates/assets/location_detail.html +++ b/src/templates/assets/location_detail.html @@ -164,6 +164,7 @@

{{ child.name }}

+ @@ -175,6 +176,15 @@

{{ child.name }}

{% for asset in page_obj %} + @@ -202,7 +212,15 @@

{{ child.name }}

{% for asset in page_obj %} - From f0a339a42301c2d899c0ace01dc1a3dac185e20b Mon Sep 17 00:00:00 2001 From: Andrew Yager Date: Sat, 28 Feb 2026 15:24:51 +1100 Subject: [PATCH 2/3] docs: add branching and release workflow to CLAUDE.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the develop → main release flow so Claude Code knows feature branches PR to develop, not main. Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 8d7c0ff..5ddcfd3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -41,6 +41,15 @@ docker compose exec web python manage.py createsuperuser docker compose exec web python manage.py setup_groups ``` +## Branching and Release Workflow + +- **`main`** — production branch. Only updated via PR from `develop`. +- **`develop`** — integration branch. All feature work merges here first. +- **Feature branches** — branch from `develop`, PR back to `develop`. +- **Release flow**: `feature-branch → develop (PR) → main (PR)`. Never PR directly to `main` from a feature branch. +- **Hotfixes**: branch from `main`, PR to `main`, then cherry-pick or merge back to `develop`. +- When committing directly to `develop` (e.g. small fixes), no PR is needed for the `develop` commit itself — the PR happens when `develop` merges to `main`. + ## Architecture ### Django Apps From e08044f5cf7f75fd35acae69f78a5a5bd27374ae Mon Sep 17 00:00:00 2001 From: Andrew Yager Date: Sat, 28 Feb 2026 15:33:41 +1100 Subject: [PATCH 3/3] fix: expose is_checkable checkbox on location edit form The is_checkable field was defined in LocationForm but never rendered in the template, making location checkout impossible to enable through the UI. Add the checkbox with a help text explaining its purpose (portable containers, not rooms). Co-Authored-By: Claude Opus 4.6 --- src/templates/assets/location_form.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/templates/assets/location_form.html b/src/templates/assets/location_form.html index c2e180f..f73d3cf 100644 --- a/src/templates/assets/location_form.html +++ b/src/templates/assets/location_form.html @@ -54,6 +54,14 @@

Active

+ +
+ {{ form.is_checkable }} +
+ +

Enable check-out/check-in for this location as a unit. Intended for portable containers (boxes, cases, flight cases).

+
+
Name Barcode Category
+
+ {% if asset.primary_image %} + + {% else %} + + {% endif %} +
+
{{ asset.name }}