Implement entity submission services for ThrillWiki

- Added BaseEntitySubmissionService as an abstract base for entity submissions.
- Created specific submission services for entities: Park, Ride, Company, RideModel.
- Implemented create, update, and delete functionalities with moderation workflow.
- Enhanced logging and validation for required fields.
- Addressed foreign key handling and special field processing for each entity type.
- Noted existing issues with JSONField usage in Company submissions.
This commit is contained in:
pacnpal
2025-11-08 22:23:41 -05:00
parent 9122320e7e
commit 2884bc23ce
29 changed files with 8699 additions and 330 deletions

View File

@@ -74,6 +74,7 @@ class ContentSubmission(BaseModel):
('create', 'Create'),
('update', 'Update'),
('delete', 'Delete'),
('review', 'Review'),
]
submission_type = models.CharField(

View File

@@ -171,6 +171,10 @@ class ModerationService:
This method uses atomic transactions to ensure all-or-nothing behavior.
If any part fails, the entire operation is rolled back.
Handles different submission types polymorphically:
- 'review': Delegates to ReviewSubmissionService to create Review record
- 'create'/'update'/'delete': Applies changes to entity directly
Args:
submission_id: UUID of submission
reviewer: User approving the submission
@@ -192,26 +196,73 @@ class ModerationService:
if not submission.can_review(reviewer):
raise ValidationError("Submission cannot be reviewed at this time")
# Apply all changes
entity = submission.entity
if not entity:
raise ValidationError("Entity no longer exists")
# Get all pending items
items = submission.items.filter(status='pending')
for item in items:
# Apply change to entity
if item.change_type in ['add', 'modify']:
setattr(entity, item.field_name, item.new_value)
elif item.change_type == 'remove':
setattr(entity, item.field_name, None)
# POLYMORPHIC HANDLING BASED ON SUBMISSION TYPE
if submission.submission_type == 'review':
# Handle review submissions - delegate to ReviewSubmissionService
logger.info(f"Approving review submission {submission_id}")
# Mark item as approved
item.approve(reviewer)
# Save entity (this will trigger versioning through lifecycle hooks)
entity.save()
from apps.reviews.services import ReviewSubmissionService
review = ReviewSubmissionService.apply_review_approval(submission)
# Mark all items as approved
for item in items:
item.approve(reviewer)
logger.info(f"Review created: {review.id} from submission {submission_id}")
elif submission.submission_type in ['create', 'update', 'delete']:
# Handle entity submissions
entity = submission.entity
if not entity:
raise ValidationError("Entity no longer exists")
logger.info(f"Approving {submission.submission_type} submission {submission_id}")
if submission.submission_type == 'create':
# Entity was created in draft state, now apply all fields and make visible
for item in items:
if item.change_type in ['add', 'modify']:
setattr(entity, item.field_name, item.new_value)
item.approve(reviewer)
entity.save()
elif submission.submission_type == 'update':
# Apply updates to existing entity
for item in items:
if item.change_type in ['add', 'modify']:
setattr(entity, item.field_name, item.new_value)
elif item.change_type == 'remove':
setattr(entity, item.field_name, None)
item.approve(reviewer)
entity.save()
elif submission.submission_type == 'delete':
# Check deletion type from metadata
deletion_type = submission.metadata.get('deletion_type', 'soft')
if deletion_type == 'soft':
# Soft delete: Apply status change to 'closed'
for item in items:
if item.field_name == 'status':
# Apply status change
setattr(entity, 'status', 'closed')
item.approve(reviewer)
entity.save()
logger.info(f"Entity soft-deleted (status=closed): {entity.id}")
else:
# Hard delete: Remove from database
for item in items:
item.approve(reviewer)
entity.delete()
logger.info(f"Entity hard-deleted from database: {entity.id}")
logger.info(f"Entity changes applied for submission {submission_id}")
else:
raise ValidationError(f"Unknown submission type: {submission.submission_type}")
# Approve submission (FSM transition)
submission.approve(reviewer)