feat: complete monorepo structure with frontend and shared resources

- Add complete backend/ directory with full Django application
- Add frontend/ directory with Vite + TypeScript setup ready for Next.js
- Add comprehensive shared/ directory with:
  - Complete documentation and memory-bank archives
  - Media files and avatars (letters, park/ride images)
  - Deployment scripts and automation tools
  - Shared types and utilities
- Add architecture/ directory with migration guides
- Configure pnpm workspace for monorepo development
- Update .gitignore to exclude .django_tailwind_cli/ build artifacts
- Preserve all historical documentation in shared/docs/memory-bank/
- Set up proper structure for full-stack development with shared resources
This commit is contained in:
pacnpal
2025-08-23 18:40:07 -04:00
parent b0e0678590
commit d504d41de2
762 changed files with 142636 additions and 0 deletions

View File

@@ -0,0 +1,170 @@
# Park Search Implementation
## Overview
Integration of the parks app with the site-wide search system, providing both full search functionality and quick search for dropdowns.
## Components
### 1. Filter Configuration (parks/filters.py)
```python
ParkFilter = create_model_filter(
model=Park,
search_fields=['name', 'description', 'location__city', 'location__state', 'location__country'],
mixins=[LocationFilterMixin, RatingFilterMixin, DateRangeFilterMixin],
additional_filters={
'status': {
'field_class': 'django_filters.ChoiceFilter',
'field_kwargs': {
'choices': Park._meta.get_field('status').choices,
'empty_label': 'Any status',
'null_label': 'Unknown'
}
},
'opening_date': {
'field_class': 'django_filters.DateFromToRangeFilter',
'field_kwargs': {
'label': 'Opening date range',
'help_text': 'Enter dates in YYYY-MM-DD format'
}
},
# Additional filters for rides, size, etc.
}
)
```
### 2. View Implementation (parks/views.py)
#### Full Search (ParkListView)
```python
class ParkListView(HTMXFilterableMixin, ListView):
model = Park
filter_class = ParkFilter
paginate_by = 20
def get_queryset(self):
try:
return (
super()
.get_queryset()
.select_related("owner")
.prefetch_related(
"photos",
"location",
"rides",
"rides__manufacturer"
)
.annotate(
total_rides=Count("rides"),
total_coasters=Count("rides", filter=Q(rides__category="RC")),
)
)
except Exception as e:
messages.error(self.request, f"Error loading parks: {str(e)}")
return Park.objects.none()
```
#### Quick Search
```python
def search_parks(request):
try:
queryset = (
Park.objects.prefetch_related('location', 'photos')
.order_by('name')
)
filter_params = {'search': request.GET.get('q', '').strip()}
park_filter = ParkFilter(filter_params, queryset=queryset)
parks = park_filter.qs[:10]
return render(request, "parks/partials/park_search_results.html", {
"parks": parks,
"is_quick_search": True
})
except Exception as e:
return render(..., {"error": str(e)})
```
### 3. Template Structure
#### Main Search Page (parks/templates/parks/park_list.html)
- Extends: search/layouts/filtered_list.html
- Blocks:
* filter_errors: Validation error display
* list_header: Park list header + actions
* filter_section: Filter form with clear option
* results_section: Park results with pagination
#### Results Display (search/templates/search/partials/park_results.html)
- Full park information
- Status indicators
- Ride statistics
- Location details
- Error state handling
#### Quick Search Results (parks/partials/park_search_results.html)
- Simplified park display
- Basic location info
- Fallback for missing images
- Error handling
### 4. Error Handling
#### View Level
- Try/except blocks around queryset operations
- Filter validation errors captured
- Generic error states handled
- User-friendly error messages
#### Template Level
- Error states in both quick and full search
- Safe data access (using with and conditionals)
- Fallback content for missing data
- Clear error messaging
### 5. Query Optimization
#### Full Search
- select_related: owner
- prefetch_related: photos, location, rides, rides__manufacturer
- Proper annotations for counts
- Pagination for large results
#### Quick Search
- Limited to 10 results
- Minimal related data loading
- Basic ordering optimization
### 6. Known Limitations
1. Testing Coverage
- Need unit tests for filters
- Need integration tests for error cases
- Need performance testing
2. Performance
- Large dataset behavior unknown
- Complex filter combinations untested
3. Security
- SQL injection prevention needs review
- Permission checks need audit
4. Accessibility
- ARIA labels needed
- Color contrast validation needed
### 7. Next Steps
1. Testing
- Implement comprehensive test suite
- Add performance benchmarks
- Test edge cases
2. Monitoring
- Add error logging
- Implement performance tracking
- Add usage analytics
3. Optimization
- Profile query performance
- Optimize filter combinations
- Consider caching strategies

View File

@@ -0,0 +1,60 @@
---
# Ride Search Feature Specification
## Overview
Extend the existing park search infrastructure to support searching rides. This follows the established:
- Authentication-first
- BaseAutocomplete pattern
- HTMX + AlpineJS frontend
Rides are related to parks via a ForeignKey. Search results must reference both ride and parent park.
## Technical Specification
### Models & Filters
- Model: `Ride` in [`rides/models.py`](rides/models.py:1) with fields `name`, `park` (ForeignKey → Park), `duration`, `thrill_rating`, etc.
- Filter: `RideFilter` in [`search/filters.py`](search/filters.py:1) (create if missing) supporting `min_thrill`, `max_duration`, and `park__id`.
### Autocomplete
- Class [`RideAutocomplete`](search/mixins.py:1) extends [`BaseAutocomplete`](core/forms.py:1).
- Query: `Ride.objects.filter(name__icontains=query)` limited to 10 results.
### Search Form
- Class [`RideSearchForm`](search/forms.py:1) uses autocomplete widget bound to [`RideAutocomplete`](search/mixins.py:1).
- Fields: `query` (CharField), `park` (HiddenField or Select), `min_thrill`, `max_duration`.
### Views & Templates
- View [`RideSearchView`](rides/views.py:1) decorated with `@login_required`.
- URL route `'search/rides/'` in [`search/urls.py`](search/urls.py:1).
- Partial template [`search/templates/search/partials/_ride_search.html`](search/templates/search/partials/_ride_search.html:1) with HTMX attributes (`hx-get`, `hx-trigger="input changed delay:300ms"`).
## File & Component Structure
- memory-bank/features/search/rides.md
- search/mixins.py add [`RideAutocomplete`](search/mixins.py:1)
- search/forms.py add [`RideSearchForm`](search/forms.py:1)
- search/urls.py register ride endpoints (`autocomplete/`, `results/`)
- rides/views.py add [`RideSearchView`](rides/views.py:1)
- search/templates/search/partials/_ride_search.html
- rides/templates/rides/partials/ride_results.html
## Integration Points
- Combined search component toggles between park and ride modes.
- Ride result links to [`ParkDetailView`](parks/views.py:1) for context.
- Shared styles and layout from [`search/templates/search/layouts/base.html`](search/templates/search/layouts/base.html:1).
## Database Query Optimization
- Add DB index on `Ride.name` and `Ride.park_id`.
- Use `select_related('park')` in view/queryset.
- Limit autocomplete to top 10 for responsiveness.
## Frontend Component Design
- HTMX: `<input>` with `hx-get="/search/rides/autocomplete/"`, update target container.
- AlpineJS: manage local state for selection, clearing on blur.
- Reuse CSS classes from park search for unified UX.
## Testing Strategy
- Unit tests for [`RideAutocomplete`](search/tests/test_autocomplete.py).
- Form tests for [`RideSearchForm`](search/tests/test_forms.py).
- View tests (`login_required`, filter logic) in [`rides/tests/test_search_view.py`].
- HTMX integration: AJAX responses include expected HTML using pytest-django + django-htmx.
- Performance: benchmark large resultset to ensure truncation and quick response.

View File

@@ -0,0 +1,142 @@
# Park Search Testing Implementation
## Test Structure
### 1. Model Tests (parks/tests/test_models.py)
#### Park Model Tests
- Basic CRUD Operations
* Creation with required fields
* Update operations
* Deletion and cascading
* Validation rules
- Slug Operations
* Auto-generation on creation
* Historical slug tracking and lookup (via HistoricalSlug model)
* pghistory integration for model tracking
* Uniqueness constraints
* Fallback lookup strategies
- Location Integration
* Formatted location string
* Coordinates retrieval
* Location relationship integrity
- Status Management
* Default status
* Status color mapping
* Status transitions
- Property Methods
* formatted_location
* coordinates
* get_status_color
### 2. Filter Tests (parks/tests/test_filters.py)
#### Search Functionality
- Text Search Fields
* Name searching
* Description searching
* Location field searching (city, state, country)
* Combined field searching
#### Filter Operations
- Status Filtering
* Each status value
* Empty/null handling
* Invalid status values
- Date Range Filtering
* Opening date ranges
* Invalid date formats
* Edge cases (future dates, very old dates)
- Company/Owner Filtering
* Existing company
* No owner (null)
* Invalid company IDs
- Numeric Filtering
* Minimum rides count
* Minimum coasters count
* Minimum size validation
* Negative value handling
#### Mixin Integration
- LocationFilterMixin
* Distance-based filtering
* Location search functionality
- RatingFilterMixin
* Rating range filtering
* Invalid rating values
- DateRangeFilterMixin
* Date range application
* Invalid date handling
## Implementation Status
### Completed
1. ✓ Created test directory structure
2. ✓ Set up test fixtures in both test files
3. ✓ Implemented Park model tests
- Basic CRUD operations
- Advanced slug functionality:
* Automatic slug generation from name
* Historical slug tracking with HistoricalSlug model
* Dual tracking with pghistory integration
* Comprehensive lookup system with fallbacks
- Status color mapping with complete coverage
- Location integration with error handling
- Property methods with null safety
4. ✓ Implemented ParkFilter tests
- Text search with multiple field support
- Status filtering with validation and choice handling
- Date range filtering with format validation
- Company/owner filtering with comprehensive null handling
- Numeric filtering with integer validation and bounds checking
- Empty value handling across all filters
- Test coverage for edge cases and invalid inputs
- Performance validation for complex filter combinations
### Next Steps
1. Performance Optimization
- [ ] Add query count assertions to tests
- [ ] Profile filter combinations impact
- [ ] Implement caching for common filters
- [ ] Add database indexes for frequently filtered fields
2. Monitoring and Analytics
- [ ] Add filter usage tracking
- [ ] Implement performance monitoring
- [ ] Track common filter combinations
- [ ] Monitor query execution times
3. Documentation and Maintenance
- [ ] Add filter example documentation
- [ ] Document filter combinations and best practices
- [ ] Create performance troubleshooting guide
- [ ] Add test coverage reports and analysis
4. Future Enhancements
- [ ] Add saved filter support
- [ ] Implement filter presets
- [ ] Add advanced combination operators (AND/OR)
- [ ] Support dynamic field filtering
### Running the Tests
To run the test suite:
```bash
python manage.py test parks.tests
```
To run specific test classes:
```bash
python manage.py test parks.tests.test_models.ParkModelTests
python manage.py test parks.tests.test_filters.ParkFilterTests
```