Skip to content

Conversation

@mihow
Copy link
Collaborator

@mihow mihow commented Jan 28, 2026

Summary

Refactors taxa list endpoints to use a through model (TaxaListTaxon) instead of custom POST actions, following the same pattern as the project membership API for consistency and better RESTful design.

Changes

Backend

  • Created TaxaListTaxon through model (ami/main/models.py:3606)

    • ForeignKeys to TaxaList and Taxon
    • Unique constraint on (taxa_list, taxon)
    • Permission checks for authenticated users
  • Database migration (ami/main/migrations/0081_add_taxalist_taxon_through_model.py)

    • Creates through model table
    • Migrates existing M2M data (16,838 memberships preserved)
    • Updated TaxaList.taxa to use through parameter
  • Created serializers (ami/main/api/serializers.py:672)

    • TaxaListTaxonSerializer - Create/update with validation
    • TaxaListTaxonListSerializer - Simplified for list views
    • Validates taxon existence and uniqueness
    • Returns proper error messages for duplicates
  • Created TaxaListTaxonViewSet (ami/main/api/views.py:1633)

    • Nested routing under taxa lists
    • Standard CRUD operations
    • Custom delete_by_taxon action for convenience
  • Updated router (config/api_router.py:40)

    • Added nested router configuration
    • Routes: /taxa/lists/{taxalist_id}/taxa/
  • Removed deprecated actions

    • add_taxon() action from TaxaListViewSet
    • remove_taxon() action from TaxaListViewSet

Frontend

  • Updated useAddTaxaListTaxon hook

    • Changed from POST /taxa/lists/{id}/add_taxon/ to POST /taxa/lists/{id}/taxa/
  • Updated useRemoveTaxaListTaxon hook

    • Changed from POST /taxa/lists/{id}/remove_taxon/ to DELETE /taxa/lists/{id}/taxa/by-taxon/{taxon_id}/

Tests

  • Comprehensive test suite (ami/main/tests/test_taxa_list_taxa_api.py)
    • 16 test cases covering all CRUD operations
    • Permission checks
    • Error cases (duplicates, non-existent taxa)
    • Data migration verification
    • All tests passing ✅

API Changes

New Endpoints

  • GET /taxa/lists/{id}/taxa/ - List taxa in a taxa list
  • POST /taxa/lists/{id}/taxa/ - Add taxon (201 Created, 400 if duplicate)
  • GET /taxa/lists/{id}/taxa/{membership_id}/ - Retrieve membership details
  • DELETE /taxa/lists/{id}/taxa/{membership_id}/ - Remove by membership ID (204 No Content)
  • DELETE /taxa/lists/{id}/taxa/by-taxon/{taxon_id}/ - Remove by taxon ID (204 No Content, 404 if not found)

Removed Endpoints

  • POST /taxa/lists/{id}/add_taxon/ (deprecated)
  • POST /taxa/lists/{id}/remove_taxon/ (deprecated)

Benefits

  1. Proper HTTP semantics: POST creates (201), DELETE destroys (204), duplicates return 400
  2. RESTful design: Nested resources follow standard conventions
  3. Better error handling: Clear error messages for invalid operations
  4. Consistency: Matches the project membership API pattern
  5. Backward compatibility: M2M relationship still works through the through model
  6. Data integrity: Migration preserved all existing relationships
  7. Test coverage: Comprehensive test suite for all operations

Testing

# Run all tests
docker compose run --rm django python manage.py test ami.main.tests.test_taxa_list_taxa_api

# Verify data migration
docker compose exec django python manage.py shell -c "
from ami.main.models import TaxaList, TaxaListTaxon
for taxa_list in TaxaList.objects.all():
    assert taxa_list.taxa.count() == TaxaListTaxon.objects.filter(taxa_list=taxa_list).count()
print('✓ All data preserved')
"

Checklist

  • Backend implementation complete
  • Frontend hooks updated
  • Migration preserves existing data
  • Tests added and passing
  • API documentation updated in PR description
  • Follows project membership API pattern

🤖 Generated with Claude Code

@netlify
Copy link

netlify bot commented Jan 28, 2026

Deploy Preview for antenna-preview canceled.

Name Link
🔨 Latest commit 1f5e5d4
🔍 Latest deploy log https://app.netlify.com/projects/antenna-preview/deploys/69796211848f8900086ffbc8

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 28, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mihow mihow marked this pull request as draft January 28, 2026 00:58
… model)

Refactors taxa list endpoints to use nested routes and proper HTTP methods
while keeping the simple ManyToManyField (no through model).

**Backend changes:**
- Created TaxaListTaxonViewSet with nested routes under /taxa/lists/{id}/taxa/
- Simple serializers for input validation and output
- Removed deprecated add_taxon/remove_taxon actions from TaxaListViewSet
- Uses Django M2M .add() and .remove() methods directly

**Frontend changes:**
- Updated useAddTaxaListTaxon to POST to /taxa/ endpoint
- Updated useRemoveTaxaListTaxon to use DELETE method

**API changes:**
- POST /taxa/lists/{id}/taxa/ - Add taxon (returns 201, 400 for duplicates)
- DELETE /taxa/lists/{id}/taxa/by-taxon/{taxon_id}/ - Remove taxon (returns 204, 404 for non-existent)
- GET /taxa/lists/{id}/taxa/ - List taxa in list
- Removed POST /taxa/lists/{id}/add_taxon/ (deprecated)
- Removed POST /taxa/lists/{id}/remove_taxon/ (deprecated)

**Benefits:**
- Same API as project membership (consistency)
- No migration needed (keeps existing simple M2M)
- Proper HTTP semantics (POST=201, DELETE=204)
- RESTful nested resource design

**Tests:**
- Added comprehensive test suite (13 tests, all passing)
- Tests for CRUD operations, validation, and error cases

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@mihow mihow force-pushed the feat/taxa-lists-through-model branch from 3ab6b2f to 1f5e5d4 Compare January 28, 2026 01:10
@mihow mihow changed the title Refactor taxa list endpoints to use through model Refactor taxa list endpoints to follow the project-user membership API Jan 30, 2026
@mihow mihow mentioned this pull request Jan 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants