-
Notifications
You must be signed in to change notification settings - Fork 2
Feature: create/delete instruments #513
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Add CreateInstrument Django view with form handling and validation - Implement frontend UI with CreateInstrument TypeScript module - Add CreateInstrumentValidator for frontend form validation - Add CreateInstrumentManager for API interactions and DatabaseService - Create error_codes and exceptions modules for structured error handling - Add migration 0012 for instrument creation feature - Update InstrumentName and AVResource models to support creation workflow - Update management commands (import, download, index) for creation compatibility - Update instrument views and templates with creation UI - Update Docker Compose and nginx configurations - Add comprehensive test suite for creation workflows ref: #406
- Add Django DELETE endpoint with permission checks for user-created instruments - Add confirmation modal template and delete button on detail page - Add TypeScript DeleteInstrumentManager for modal interaction and API call - Add Solr cleanup on successful deletion via transaction.on_commit - Restrict delete access to instrument creator and superusers
- Create NameRowManager class to extract duplicated name row management logic (row creation, RTL support, add/remove rows, form data collection) - Refactor AddNameManager to use NameRowManager via composition - Refactor CreateInstrumentManager to use NameRowManager via composition - Move AddName publish logic from entry point into AddNameManager for consistency - Fix DeleteNameManager to use shared getCsrfToken utility instead of private method - Update entry points (AddName.ts, CreateInstrument.ts) to follow consistent initialization pattern
PouyaMohseni
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from that, I also cannot access the instrument list endpoint. I have dropped all public schemas in Django and flushed the database, yet I still receive the following error when accessing the /instrument endpoint:
NoReverseMatch
django.urls.exceptions.NoReverseMatch: Reverse for 'instrument-detail' with arguments '('',)' not found. 1 pattern(s) tried: ['instrument/(?P<umil_id>[-a-zA-Z0-9_]+)/\\Z']
Do you have any suggestions for reindexing?
| related_name="created_instruments", | ||
| help_text="User who created this instrument (null for Wikidata imports)", | ||
| ) | ||
| source = models.CharField( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did we decide to require sources for newly added entries? I believe Ich mentioned that an instrument's source should be defined by the sources of its names.
I'm not sure which approach is the best, but at the moment we don't seem to have a clear editorial workflow for instrument names. For example, what should happen if a verified instrument ends up with no verified names (e.g., all names are removed)? Should the instrument entry itself be deleted, or should it remain as an instrument without any names?
If we decide not to require sources for instruments, the solution is straightforward delete. However, if instruments do have sources, the action becomes less clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #406 (comment)
| if not hbs_class: | ||
| return False | ||
| # Pattern: one digit (1-5), followed by another digit, optionally followed by more .digits | ||
| pattern = r"^[1-5][0-9](\.[0-9]+)*$" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is a correct validator for HBS numbers. HBS values can include plus and dash in addition to a dot. Also, the second number, like the first, should be between 1 and 5. More, 0 is not a valid value in HBS numbers. I verified this by checking the entries we pulled from Wikidata. You can also see the same function referenced in #511 NameValidator.ts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is why I suggested you to put #511 on hold. Again, this is the MVP for the instrument creation feature. The main idea is to make it work. All the addition touchup should be addressed in separate PRs.
| <a class="view-field notranslate" | ||
| href="https://www.wikidata.org/wiki/{{ instrument.wikidata_id }}" | ||
| target="_blank">{{ instrument.wikidata_id }}</a> | ||
| {% if instrument.is_user_created %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the assumption that a user created instrument does not have a Wikidata ID is wrong. When pushed to Wikidata, they are indexed. So maybe change it to whether wikidata_id exists, as what you did with mimo_class.
| <span>Add New Name: <span id="instrumentNameInModal" class="notranslate m-1"></span></span> | ||
| <br /> | ||
| <small>Wikidata ID: <span id="instrumentWikidataIdInModal" class="notranslate m-1"></span></small> | ||
| <small>UMIL ID: <span id="instrumentUmilIdInModal" class="notranslate m-1"></span></small> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need UMIL ID here as it is something internal? Also, we don't show that in instrument detail. Mybe showing that only when Wikidata ID is null?
| class="rounded mw-50" | ||
| onerror="this.onerror=null;this.src='{% static "assets/images/instruments/no-image.svg" %}';" /> | ||
| <div class="ms-2 align-self-start"> | ||
| {% if instrument.is_user_created and instrument.default_image.source_name %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think showing any uploaded image without approval to logged-out users would be a good idea, as we are not sure about the license for use and the content.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a separate issue/PR
| class="rounded mw-50" | ||
| onerror="this.onerror=null;this.src='{% static "assets/images/instruments/no-image.svg" %}';" /> | ||
| <div class="ms-2 align-self-start"> | ||
| {% if instrument.is_user_created and instrument.default_image.source_name %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe showing all image sources?
| slug_field = "umil_id" | ||
| slug_url_kwarg = "umil_id" | ||
|
|
||
| def get_object(self, queryset=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am curious whether there is a good approach to have UMIL- before the instrument ID in every request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wikidata_id is no longer required with the changes, using UMIL- is a better approach than exposing pk in the database
| instrument.avresource_set.all().delete() | ||
|
|
||
| # Delete the instrument (InstrumentNames cascade automatically) | ||
| instrument.delete() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering whether it is better to perform soft delete or to retire the current UMIL id.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is, but it should be handled in a separate issue/PR
| ) | ||
|
|
||
| # Only the creator or a superuser can delete | ||
| if not (request.user.is_superuser or instrument.created_by == request.user): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the original contributor of an instrument always have the ability to delete the instrument? There might be many other name contributions to that entry by other users, or we might have already pushed the instrument entry to Wikidata. If a user decides to delete their contribution, it could undermine the other contributions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, this should be handled in a followup issue/PR
PouyaMohseni
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from that, I also cannot access the instrument list endpoint. I have dropped all public schemas in Django and flushed the database, yet I still receive the following error when accessing the /instrument endpoint:
NoReverseMatch
django.urls.exceptions.NoReverseMatch: Reverse for 'instrument-detail' with arguments '('',)' not found. 1 pattern(s) tried: ['instrument/(?P<umil_id>[-a-zA-Z0-9_]+)/\\Z']
Do you have any suggestions for reindexing?
Have you migrated yet? |
ref: #406
preview:
