Compare commits

...

166 Commits
nuxt ... main

Author SHA1 Message Date
pacnpal
679de16e4f Refactor account adapters and admin classes; enhance type hinting for better clarity and maintainability, ensuring consistent typing across methods and improving overall code quality. 2025-09-27 11:59:29 -04:00
pacnpal
31a2d84f9f Refactor type checking configuration; consolidate settings from pyrightconfig.json into pyproject.toml for improved project structure and clarity. 2025-09-27 11:48:31 -04:00
pacnpal
7d04c2baa0 Refactor environment variable configurations for consistency; ensure proper type casting for DEBUG and ALLOWED_HOSTS settings. 2025-09-27 11:42:25 -04:00
pacnpal
6575ea68c7 Add advanced search and trending parks features; update frontend dependencies and enhance home page layout 2025-09-27 09:42:12 -04:00
pacnpal
e1cb76f1c6 Refactor ParkLocation model to inherit from TrackedModel for enhanced history tracking. Update point handling to temporarily store coordinates as a string. Implement Haversine formula for distance calculation as a placeholder until PostGIS is enabled.
Refactor advanced search template to utilize Alpine.js for state management. Enhance search functionality with dynamic view modes and improved filter handling using HTMX.
2025-09-26 15:56:28 -04:00
pacnpal
acc8308fd2 Refactor location widget to utilize Alpine.js for state management and HTMX for AJAX interactions. Removed legacy JavaScript functions and streamlined event handling for improved user experience. 2025-09-26 15:42:07 -04:00
pacnpal
de8b6f67a3 Refactor ride filters and forms to use AlpineJS for state management and HTMX for AJAX interactions
- Enhanced filter sidebar with AlpineJS for collapsible sections and localStorage persistence.
- Removed custom JavaScript in favor of AlpineJS for managing filter states and interactions.
- Updated ride form to utilize AlpineJS for handling manufacturer, designer, and ride model selections.
- Simplified search script to leverage AlpineJS for managing search input and suggestions.
- Improved error handling for HTMX requests with minimal JavaScript.
- Refactored ride form data handling to encapsulate logic within an AlpineJS component.
2025-09-26 15:25:12 -04:00
pacnpal
c437ddbf28 Enhance moderation dashboard with Alpine.js for improved state management and event handling. Added x-data and event listener for retry functionality. 2025-09-26 14:53:17 -04:00
pacnpal
f7b1296263 Refactor moderation dashboard and advanced search components to utilize Alpine.js for improved state management. Enhanced event handling and user experience by replacing legacy JavaScript functions with Alpine.js reactive methods. Updated auth modal comparison and button comparison tests to leverage Alpine.js for better interactivity and functionality. 2025-09-26 14:48:13 -04:00
pacnpal
e53414d795 Refactor park search results and search suggestions to utilize Alpine.js for improved state management. Enhanced event handling and user experience by replacing legacy JavaScript functions with Alpine.js reactive methods. 2025-09-26 14:39:15 -04:00
pacnpal
2328c919c9 Refactor ride model form to remove legacy JavaScript functions. Streamlined event handling by leveraging Alpine.js for improved state management and user experience. 2025-09-26 14:35:39 -04:00
pacnpal
09e2c69493 Refactor designer, manufacturer, and ride model forms to utilize Alpine.js for state management. Improved form submission handling, HTMX event integration, and enhanced user experience through better event dispatching and modal management. 2025-09-26 14:34:59 -04:00
pacnpal
5b7b203619 Refactor add ride modal to utilize Alpine.js for state management. Improved modal open/close functionality and enhanced event handling for better user experience. 2025-09-26 14:32:10 -04:00
pacnpal
47c435d2f5 Refactor ride model search results template to utilize Alpine.js for state management. Enhanced selection handling and improved event dispatching for better user experience. 2025-09-26 14:31:15 -04:00
pacnpal
ce382a4361 Refactor designer search results template to utilize Alpine.js for state management. Enhanced designer selection handling and improved event dispatching for better user experience. 2025-09-26 14:30:22 -04:00
pacnpal
07ab9f28f2 Refactor manufacturer search results template to utilize Alpine.js for state management. Enhanced manufacturer selection handling and improved event dispatching for better user experience. 2025-09-26 14:29:37 -04:00
pacnpal
40e5cf3162 Refactor ride form template to utilize Alpine.js for state management. Enhanced form submission handling and improved search result clearing functionality for better user experience. 2025-09-26 14:27:47 -04:00
pacnpal
b9377ead37 Refactor designer and ride model search results templates to utilize Alpine.js for state management. Enhanced selection functionality and improved event handling for better user experience. 2025-09-26 14:23:03 -04:00
pacnpal
851709058f Refactor location widget and park search results templates to utilize Alpine.js for state management. Enhanced search functionality, improved data binding, and streamlined event handling for better user experience. 2025-09-26 14:21:28 -04:00
pacnpal
757ad1be89 Refactor location results, universal map, and road trip planner templates to utilize Alpine.js for state management and event handling. Enhanced geolocation button functionality, improved map initialization, and streamlined trip management interactions. 2025-09-26 13:55:06 -04:00
pacnpal
d4431acb39 Refactor search results template to utilize Alpine.js for view switching and state management. Enhanced view mode handling and integrated HTMX for improved search functionality. 2025-09-26 13:50:31 -04:00
pacnpal
f8907c7778 Refactor park and ride detail templates to utilize Alpine.js for state management in photo galleries and upload modals. Enhanced photo handling and initialization logic for improved user experience. 2025-09-26 13:46:48 -04:00
pacnpal
8c0c3df21a Refactor templates to utilize AlpineJS for state management and interactions, replacing custom JavaScript. Updated navigation links for parks and rides, streamlined mobile filter functionality, and enhanced advanced search features. Removed legacy JavaScript code for improved performance and maintainability. 2025-09-26 13:43:14 -04:00
pacnpal
9b2124867a Add PostgreSQL test settings for thrillwiki project 2025-09-26 11:32:03 -04:00
pacnpal
12deafaa09 Refactor photo management and upload functionality to use HTMX for asynchronous requests
- Updated photo upload handling in `photo_manager.html` and `photo_upload.html` to utilize HTMX for file uploads, improving user experience and reducing reliance on Promises.
- Refactored caption update and primary photo toggle methods to leverage HTMX for state updates without full page reloads.
- Enhanced error handling and success notifications using HTMX events.
- Replaced fetch API calls with HTMX forms in various templates, including `homepage.html`, `park_form.html`, and `roadtrip_planner.html`, to streamline AJAX interactions.
- Improved search suggestion functionality in `search_script.html` by implementing HTMX for fetching suggestions, enhancing performance and user experience.
- Updated designer, manufacturer, and ride model forms to handle responses with HTMX, ensuring better integration and user feedback.
2025-09-26 10:18:56 -04:00
pacnpal
8aa56c463a Add initial migration for moderation app and document seed command database migration issue
- Created an empty migration file for the moderation app to address missing migrations.
- Documented the root cause analysis and solution steps for the seed command failure due to missing moderation tables.
- Identified and resolved a VARCHAR(10) constraint violation in the User model during seed command execution.
- Updated seed command logic to ensure compliance with field length constraints.
2025-09-25 08:39:09 -04:00
pacnpal
41b3c86437 Add initial migration for moderation app and resolve seed command issues
- Created an empty migration file for the moderation app to enable migrations.
- Documented the resolution of the seed command failure due to missing moderation tables.
- Identified and fixed a VARCHAR(10) constraint violation in the User model during seed data generation.
- Updated role assignment in the seed command to comply with the field length constraint.
2025-09-25 08:39:05 -04:00
pacnpal
b1c369c1bb Add park and ride card components with advanced search functionality
- Implemented park card component with image, status badge, favorite button, and quick stats overlay.
- Developed ride card component featuring thrill level badge, status badge, favorite button, and detailed stats.
- Created advanced search page with filters for parks and rides, including location, type, status, and thrill level.
- Added dynamic quick search functionality with results display.
- Enhanced user experience with JavaScript for filter toggling, range slider updates, and view switching.
- Included custom CSS for improved styling of checkboxes and search results layout.
2025-09-24 23:10:48 -04:00
pacnpal
4373d18176 Remove deprecated scripts and assets related to ThrillWiki deployment and validation
- Deleted the systemd service diagnosis script `test-systemd-service-diagnosis.sh`
- Removed the validation fix test script `test-validation-fix.sh`
- Eliminated the simple validation test script `validate-step5b-simple.sh`
- Removed the GitHub webhook listener script `webhook-listener.py`
- Deleted various placeholder images from the static assets
- Removed the ThrillWiki database file `thrillwiki.db`
2025-09-24 21:21:50 -04:00
pacnpal
82cbdecc4c Remove verification script for tuple fallbacks
This commit deletes the `verify_no_tuple_fallbacks.py` script, which was used to independently verify the elimination of tuple fallback patterns in the codebase. The script included functionality to search for specific fallback patterns and verify the removal of related functions. Its removal indicates that the verification process is no longer necessary or has been integrated elsewhere.
2025-09-24 19:31:29 -04:00
pacnpal
616f6528b8 feat: Update ThrillWiki development rules and context documentation for enhanced clarity and consistency 2025-09-24 18:01:39 -04:00
pacnpal
d31e4b4ebe Add comprehensive seed data analysis and implementation plan
- Document current schema analysis for Parks, Rides, Accounts, Moderation, Core, and Media apps
- Identify key relationships, constraints, and limitations of existing seed implementation
- Outline comprehensive seed data requirements across companies, parks, rides, users, and media
- Define phased implementation strategy for seeding data
- Create detailed technical implementation notes for command structure, data sources, and performance considerations
- Implement comprehensive seed command with phase-based execution and safety features
2025-09-24 10:28:07 -04:00
pacnpal
0dd3f04137 feat: Update Cloudflare Images settings and enhance Tailwind CSS utility classes for improved styling and responsiveness 2025-09-24 10:00:12 -04:00
pacnpal
41fb41838c feat: Implement enhanced park list template with improved layout and accessibility features
- Created a new enhanced park list template with a responsive design.
- Added skip navigation links for better accessibility.
- Introduced an enhanced header section with park statistics overview.
- Developed a sidebar for advanced filters and a search section.
- Implemented loading overlay and error handling for HTMX requests.
- Enhanced park results display with animations and improved empty states.
- Added pagination controls with improved UX for navigating park listings.
2025-09-23 20:35:44 -04:00
pacnpal
fd42ee1161 Add initial ThrillWiki context configuration with project overview, technology stack, domain architecture, and development standards 2025-09-23 19:40:16 -04:00
pacnpal
33f5486000 Add comprehensive context documentation for ThrillWiki Django app 2025-09-23 19:35:57 -04:00
pacnpal
2ff0bf5243 Update .gitignore to include snapshots directory 2025-09-23 19:25:03 -04:00
pac7
00d01f567a Improve the way users can update their personal information
Update the user profile page to allow users to edit their name, email, and password.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c446bc9e-66df-438c-a86c-f53e6da13649
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-23 23:04:21 +00:00
pac7
601538b494 Improve error handling for park and area detail views
Update ParkDetailView and ParkAreaDetailView to raise Http404 exceptions instead of ObjectDoesNotExist for improved HTTP error handling.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c446bc9e-66df-438c-a86c-f53e6da13649
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-23 23:03:26 +00:00
pac7
fff180c476 Improve park listing performance with optimized queries and caching
Implement performance enhancements for park listing by optimizing database queries, introducing efficient caching mechanisms, and refining pagination for a significantly faster and smoother user experience.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c446bc9e-66df-438c-a86c-f53e6da13649
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-23 22:50:09 +00:00
pac7
6391b3d81c Enhance website accessibility and improve user interface elements
Introduce ARIA attributes, improve focus management, and refine UI element styling for better accessibility and user experience across the application.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c446bc9e-66df-438c-a86c-f53e6da13649
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-23 22:25:16 +00:00
pac7
d978217577 Enhance website's visual appeal and mobile responsiveness with style updates
Update CSS styles across various components to improve visual presentation and ensure better responsiveness on mobile devices, including adjustments to spacing, aspect ratios, and element sizing.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c446bc9e-66df-438c-a86c-f53e6da13649
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-23 22:11:05 +00:00
pac7
4c954fff6f Enhance park search with autocomplete and improved filtering options
Introduce autocomplete for park searches, optimize park data fetching with select_related and prefetch_related, add new API endpoints for autocomplete and quick filters, and refactor the park list view to use new Django Cotton components for a more dynamic and user-friendly experience.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c446bc9e-66df-438c-a86c-f53e6da13649
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-23 21:44:12 +00:00
pac7
7feb7c462d Saved your changes before starting work
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c446bc9e-66df-438c-a86c-f53e6da13649
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-23 21:24:03 +00:00
pac7
7485477e26 Adjust icon sizes for better visual appearance on the site
Update the size of theme toggle icons and the user icon in the header to improve visual consistency and display.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 9ac4060c-9ba6-40b4-b325-c945a385dd39
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/9ac4060c-9ba6-40b4-b325-c945a385dd39/fMpcdcp
2025-09-23 21:21:12 +00:00
pac7
1277835775 Adjust the size of the sun icon in the header
Update the 'enhanced_header.html' template to change the size of the sun icon (fa-sun) from h-6 w-6 to h-5 w-5.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 9ac4060c-9ba6-40b4-b325-c945a385dd39
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/9ac4060c-9ba6-40b4-b325-c945a385dd39/fMpcdcp
2025-09-23 21:19:59 +00:00
pac7
f2fccdf190 Improve icon sizes for better visual consistency across devices
Update Tailwind CSS with new height and width utilities for icons and adjust icon sizes in the enhanced header component for improved responsiveness.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 9ac4060c-9ba6-40b4-b325-c945a385dd39
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-23 21:15:44 +00:00
pac7
beac6ddfd8 Saved your changes before starting work
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 9ac4060c-9ba6-40b4-b325-c945a385dd39
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-23 21:11:56 +00:00
pac7
6e0c3121be Improve site-wide visual consistency and adherence to modern standards
Update templates, CSS, and JavaScript to ensure visual consistency. Verify theme toggle functionality and ensure adherence to best practices for Django, HTMX, and AlpineJS, leveraging Django Cotton effectively.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 48ecdb60-d0f0-4b75-95c9-34e409ef35fb
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 16:16:55 +00:00
pac7
691f018e56 Improve visual consistency and modern standards across the website
Add CSP nonce to script tags in park_detail.html and update Park model to potentially handle historical events.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 48ecdb60-d0f0-4b75-95c9-34e409ef35fb
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 16:16:26 +00:00
pac7
6697d8890b Enhance website security and add SEO meta tags for better visibility
Implement robust security headers, including CSP with nonces, and integrate comprehensive SEO meta tags into the base template and homepage. Add inline styles for CSP compliance and improve theme management script for immediate theme application.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 48ecdb60-d0f0-4b75-95c9-34e409ef35fb
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 16:06:47 +00:00
pac7
95f94cc799 Improve site performance and adhere to best practices
Optimize database queries for parks and rides using select_related and prefetch_related, implement caching for homepage stats and trending items, and update the ride detail template to remove unnecessary link wrapping.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 48ecdb60-d0f0-4b75-95c9-34e409ef35fb
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 15:45:51 +00:00
pac7
cb3a9ddf3f Improve website's visual consistency and adherence to modern standards
This commit refactors various frontend components and templates to ensure visual consistency across the site, improves the theme toggle functionality, and aligns the codebase with best practices for Django, HTMX, and Alpine.js, while maximizing the utilization of Django Cotton.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 48ecdb60-d0f0-4b75-95c9-34e409ef35fb
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 15:30:55 +00:00
pac7
6d30131f2c Improve park detail page map display for better user experience
Refactor park detail template to use data attributes on the map div for latitude, longitude, and park name, simplifying map initialization and handling missing location data gracefully.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 48ecdb60-d0f0-4b75-95c9-34e409ef35fb
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 15:20:45 +00:00
pac7
5737e5953d Improve park detail page by integrating map data
Refactors the park detail template to pass map coordinates and park name as data attributes to a hidden div, which is then used to initialize the park map via JavaScript.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 48ecdb60-d0f0-4b75-95c9-34e409ef35fb
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 15:18:50 +00:00
pac7
789d5db37a Improve card display by adjusting height for better visibility
Remove fixed height attribute from park and ride card components in templates/home.html to resolve potential rendering issues.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/0bdea3fb-49ea-4863-b501-fa6f5af0cbf0/gnWxH6v
2025-09-22 15:08:23 +00:00
pac7
b8891fc65f Add binding to card components to display data correctly
Update various HTML templates to use Vue.js binding syntax (':') for passing data to custom components like `c-park_card` and `c-ride_card`, resolving issues with data not being displayed.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/0bdea3fb-49ea-4863-b501-fa6f5af0cbf0/DkyJkDK
2025-09-22 15:03:15 +00:00
pac7
331329d1ec Display images on park and ride cards using new card image field
Update park and ride card templates to utilize the `card_image` field for displaying images, with fallbacks to existing image fields or placeholders.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/0bdea3fb-49ea-4863-b501-fa6f5af0cbf0/0NbnR7B
2025-09-22 14:53:02 +00:00
pac7
120f215cad Ensure parks always have a valid slug for proper identification
Add validation to prevent parks from being created or updated without a slug.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 14:51:06 +00:00
pac7
707546f279 Improve park status display and add new styles for dark mode
Update park status handling to include more variations and add new dark mode CSS classes for purple and yellow color schemes.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 14:50:43 +00:00
pac7
b67353eff9 Update styling and ensure park slugs are not empty
Remove unused Tailwind CSS classes and add a check to prevent empty slugs for parks.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 14:46:09 +00:00
pac7
2cad07c198 Improve park display by adding default values and fixing UI elements
Remove unused gradient and background utility classes from Tailwind CSS. Update featured_parks.html to handle missing park images and ensure a slug is always present for park links.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 14:43:07 +00:00
pac7
30997cb615 Improve park detail page layout and ride display
Adds responsive grid column classes to Tailwind CSS and updates the park detail template to use a new custom component for displaying rides, removing direct links for property owner names.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 14:40:47 +00:00
pac7
0ee6e8c820 Ensure park and ride slugs are valid before displaying links
Prevents 500 errors by filtering out parks and rides with null or empty slugs from trending lists and excludes them from database queries where slugs are required. Additionally, it adds conditional rendering in templates to handle parks without slugs gracefully.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 14:36:17 +00:00
pac7
1a8171f918 Update park and ride cards to use django-cotton components
Standardize park and ride card UI by refactoring existing components into reusable django-cotton components and enforce the use of django-cotton for future card development.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 03:36:17 +00:00
pac7
ffebd5ce01 Standardize park and ride cards with django-cotton component
Updates CSS with new Tailwind classes and refactors ride card template to use django-cotton, implementing park-specific URL generation and graceful handling of missing slugs.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 03:35:47 +00:00
pac7
97bf980e45 Standardize park and ride display cards using django-cotton
Replace custom park and ride card templates with django-cotton components, ensuring a consistent UI and enforcing its usage.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 03:30:23 +00:00
pac7
3beeb91c7f Standardize UI card components using Django Cotton and enforce its usage
Update documentation to mandate Django Cotton components for all new card UIs, including specific rules for organization, naming, and usage of park and ride card components, along with guidelines for migration and exceptions.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 03:21:55 +00:00
pac7
25e6fdb496 Standardize park and ride cards using Django Cotton components
Introduces reusable Django Cotton components for park and ride cards, standardizing their presentation and enforcing the use of the django-cotton templating system. Updates static CSS for new color variables and gradient stops.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 03:21:14 +00:00
pac7
0331e2087a Add styles for browse menu and button functionality
Remove browse menu and button styles from tailwind.css and move them to input.css.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c537be14-ffc2-48de-88ef-2bdd9e6ae15a
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/c537be14-ffc2-48de-88ef-2bdd9e6ae15a/oDeWG1n
2025-09-22 03:11:46 +00:00
pac7
1511fcfcfe Add styles for the browse menu and update color definitions
Adds new CSS class styles for the browse menu functionality and its associated components, including animations and responsive adjustments. Updates various color definitions in `tailwind.css` to include new shades and ensure consistency.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c537be14-ffc2-48de-88ef-2bdd9e6ae15a
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/c537be14-ffc2-48de-88ef-2bdd9e6ae15a/oDeWG1n
2025-09-22 03:09:52 +00:00
pacnpal
88c16be231 fix 2025-09-22 03:06:37 +00:00
pac7
3830b1ed50 Adjust layout for improved responsiveness and wider content display
Modify the max-width of the enhanced header component to 'auto' and 'max-w-4xl' to accommodate wider content and improve responsiveness.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c537be14-ffc2-48de-88ef-2bdd9e6ae15a
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/c537be14-ffc2-48de-88ef-2bdd9e6ae15a/oDeWG1n
2025-09-22 03:05:39 +00:00
pac7
db1441fcd2 Adjust layout to ensure content containers display properly
Updates the container width in the UI to fix display issues.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c537be14-ffc2-48de-88ef-2bdd9e6ae15a
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/c537be14-ffc2-48de-88ef-2bdd9e6ae15a/OEYCULv
2025-09-22 03:04:48 +00:00
pac7
b3e56ed465 Improve layout and text wrapping in the header dropdown menu
Adjusted dropdown width and flex item styling in enhanced_header.html to fix text wrapping issues and improve vertical alignment.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c537be14-ffc2-48de-88ef-2bdd9e6ae15a
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/c537be14-ffc2-48de-88ef-2bdd9e6ae15a/OEYCULv
2025-09-22 02:40:34 +00:00
pac7
6adbaf885f Adjust layout to ensure content displays correctly without overlapping
Replaces grid layout with flexbox in enhanced_header.html to resolve column width issues caused by gap-8.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c537be14-ffc2-48de-88ef-2bdd9e6ae15a
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/c537be14-ffc2-48de-88ef-2bdd9e6ae15a/DIBq8v8
2025-09-22 02:37:08 +00:00
pacnpal
ee57a9ada1 ok 2025-09-22 02:24:45 +00:00
pacnpal
66f57448be Refine browse menu styles for improved layout and accessibility 2025-09-21 22:23:22 -04:00
pac7
9d776aa5e3 Remove high contrast mode media query due to browser compatibility issues
Remove the `@media (prefers-contrast: high)` query from `static/css/components.css` as it caused browser compatibility issues, as indicated by parsing errors in `attached_assets/Pasted-Found-invalid-value-for-media-feature-components-css-476-26-Error-in-parsing-value-for-webkit-tex-1758506979647_1758506979648.txt`.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c537be14-ffc2-48de-88ef-2bdd9e6ae15a
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/c537be14-ffc2-48de-88ef-2bdd9e6ae15a/I31VUJS
2025-09-22 02:11:04 +00:00
pac7
b265d793a3 Update styles to use plain CSS instead of @apply directives
Converts CSS from Tailwind's @apply directive to plain CSS for improved compatibility with Tailwind 4 and better maintainability.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c537be14-ffc2-48de-88ef-2bdd9e6ae15a
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/c537be14-ffc2-48de-88ef-2bdd9e6ae15a/C5U8Nxc
2025-09-22 02:09:35 +00:00
pac7
8c85963817 Update browse menu styles for Tailwind 4 compatibility
Replaced Tailwind CSS @apply directives with explicit class definitions in `templates/components/layout/enhanced_header.html` and removed custom CSS rules from `static/css/components.css` to resolve compatibility issues with Tailwind 4.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c537be14-ffc2-48de-88ef-2bdd9e6ae15a
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/c537be14-ffc2-48de-88ef-2bdd9e6ae15a/pUkRa4J
2025-09-22 02:07:43 +00:00
pac7
09f20c640d Update CSS to use plain styles instead of Tailwind CSS @apply directives
Replaces Tailwind CSS @apply directives with plain CSS properties in `components.css` to resolve build errors and ensure proper styling.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c537be14-ffc2-48de-88ef-2bdd9e6ae15a
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/c537be14-ffc2-48de-88ef-2bdd9e6ae15a/76uBCoz
2025-09-22 02:03:43 +00:00
pac7
932deb876a Improve the appearance and layout of the browse dropdown menu
Refactor static/css/components.css and templates/components/layout/enhanced_header.html to introduce specific styles for the browse dropdown menu, including width, grid layout, and item styling using Tailwind CSS classes.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c537be14-ffc2-48de-88ef-2bdd9e6ae15a
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/c537be14-ffc2-48de-88ef-2bdd9e6ae15a/76uBCoz
2025-09-22 02:02:27 +00:00
pac7
7e9bd41316 Improve the overall appearance and user experience of the website
No changes made to the codebase.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c537be14-ffc2-48de-88ef-2bdd9e6ae15a
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/c537be14-ffc2-48de-88ef-2bdd9e6ae15a/c8DPZlH
2025-09-22 01:57:25 +00:00
pac7
bcdd2810a9 Improve the visual layout and spacing of the enhanced header component
Adjusted CSS classes in `enhanced_header.html` to increase the width of the dropdown menu, increase grid gap, and modify padding/margins for better visual presentation.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c537be14-ffc2-48de-88ef-2bdd9e6ae15a
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/c537be14-ffc2-48de-88ef-2bdd9e6ae15a/c8DPZlH
2025-09-22 01:57:07 +00:00
pac7
236b6f0254 Saved your changes before starting work
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c537be14-ffc2-48de-88ef-2bdd9e6ae15a
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 01:48:06 +00:00
pac7
ed400a5203 Restructure project by moving backend files to the root directory
Moves contents of the backend directory to the project root and removes the 'api' path from application routes.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 13715eac-095e-4684-9f5c-8c427c2e2dd6
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 00:36:34 +00:00
pac7
5046e55f05 Restructure project to move backend code to the root directory
Relocate backend application code from the 'apps' directory to the project root and remove '/api' paths from app configurations.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 13715eac-095e-4684-9f5c-8c427c2e2dd6
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 00:36:12 +00:00
pac7
d21ae6027d Remove temporary API integration and settings
Remove the temporary API app from LOCAL_APPS in base.py and remove API URL includes from thrillwiki/urls.py.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: bb110295-d54a-4af8-ba17-33bb9f82dfa0
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 00:30:17 +00:00
pac7
afdcfe7264 Add Django backend and configuration files to manage the application
Add Django project structure, including manage.py, settings.py, and wsgi.py, to establish the backend foundation.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: bb110295-d54a-4af8-ba17-33bb9f82dfa0
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 00:28:12 +00:00
pacnpal
b24b12080b remove apps/api 2025-09-21 20:19:50 -04:00
pacnpal
f3c59ad6ff remove backend 2025-09-21 20:19:12 -04:00
pac7
9e724bd795 Add OAuth integration for Google and Discord login
Integrates Google and Discord OAuth providers using allauth for user authentication, replacing the previous endpoint.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 9bc9dd7a-5328-4cb7-91de-b3cb33a0c48c
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 00:15:16 +00:00
pac7
a7bd0505f9 Update search and login functionality to use new endpoints
Refactor the search component to fetch results from a new endpoint and handle both JSON and HTML responses. Update the authentication modal to utilize Django's allauth for OAuth providers, handling redirects and login success/failure more robustly.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 9bc9dd7a-5328-4cb7-91de-b3cb33a0c48c
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 00:15:16 +00:00
pac7
ebe65e7c9d Update development settings to exclude Redis health checks
Temporarily remove `health_check.contrib.redis` from `INSTALLED_APPS` in `backend/config/django/local.py` for development environments.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 9bc9dd7a-5328-4cb7-91de-b3cb33a0c48c
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 00:15:16 +00:00
pac7
bddcc62ee6 Improve how JavaScript components are loaded and registered
Prevent duplicate registration of Alpine.js components by introducing a flag and ensure components are registered only once, even with multiple registration attempts.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 9bc9dd7a-5328-4cb7-91de-b3cb33a0c48c
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 00:15:16 +00:00
pac7
0153af7339 Improve compatibility with user authentication providers
Suppress specific deprecation warnings from dj_rest_auth related to user settings for better compatibility with django-allauth.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 9bc9dd7a-5328-4cb7-91de-b3cb33a0c48c
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 00:15:15 +00:00
pac7
821c94bc76 Remove unused social authentication endpoints and update frontend
Remove deprecated social provider API endpoints from the backend and update the frontend JavaScript to hardcode Google and Discord as the available social login providers.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 9bc9dd7a-5328-4cb7-91de-b3cb33a0c48c
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 00:15:15 +00:00
pac7
164cc15d90 Adjust header layout to move search button and enlarge user and theme icons
Modify the enhanced_header.html template to reposition the search button to the left, increase the size of the user icon and theme toggle buttons, and adjust the padding on the search input.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: d72060d9-0700-4897-8f16-fcb1d36ca106
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 00:15:15 +00:00
pac7
fc654543f2 Saved your changes before starting work
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: d72060d9-0700-4897-8f16-fcb1d36ca106
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 00:15:15 +00:00
pac7
60661c9041 Adjust the maximum width of the search bar component
Modify the `max-w-2xl` class to `max-w-xl` in `enhanced_header.html` to adjust the search bar's maximum width.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: d2cd90dd-df0e-4a8a-b6ca-d9a6c16df62b
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/d2cd90dd-df0e-4a8a-b6ca-d9a6c16df62b/sVelQ4G
2025-09-22 00:15:15 +00:00
pac7
1eb35bce2e Update user icon to open a menu with login or register options
Refactors the user icon component in `enhanced_header.html` to use Alpine.js for toggling a dropdown menu, displaying either user profile information or a login/register prompt.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: d2cd90dd-df0e-4a8a-b6ca-d9a6c16df62b
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/d2cd90dd-df0e-4a8a-b6ca-d9a6c16df62b/1S0572H
2025-09-22 00:15:15 +00:00
pac7
562126a3a1 Adjust header layout and enhance user authentication display
Modify backend/templates/components/layout/enhanced_header.html to refine header spacing, integrate theme toggle directly into the button element, and update user icon display logic, including handling unauthenticated users with a modal trigger.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: d2cd90dd-df0e-4a8a-b6ca-d9a6c16df62b
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/d2cd90dd-df0e-4a8a-b6ca-d9a6c16df62b/UUJxFqQ
2025-09-22 00:15:15 +00:00
pac7
081b5b7605 Update header to include logo and browse menu from enhanced header template
Integrate the logo and "Browse" menu into the header component by incorporating content from the `enhanced_header.html` template, while retaining existing header structure.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: d2cd90dd-df0e-4a8a-b6ca-d9a6c16df62b
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/d2cd90dd-df0e-4a8a-b6ca-d9a6c16df62b/UUJxFqQ
2025-09-22 00:15:15 +00:00
pac7
7fe9279d67 Restored to 'acd03ff56ba593217c7983ed5541275257390f84'
Replit-Restored-To: acd03ff56ba593217c7983ed5541275257390f84
2025-09-22 00:15:15 +00:00
pac7
12a2e9823d Saved your changes before rolling back
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: d2cd90dd-df0e-4a8a-b6ca-d9a6c16df62b
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 00:15:15 +00:00
pac7
f812a65271 Adjust spacing and size for search bar and theme toggle
Update `enhanced_header.html` to adjust gap between elements and the width of the search input.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: dcfff319-6e91-4220-98a9-8295b87755b7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/dcfff319-6e91-4220-98a9-8295b87755b7/6piZjaF
2025-09-22 00:15:15 +00:00
pac7
ac344aea92 Adjust header layout to place search between other navigation elements
Repositions the search bar within the header to prevent overlap with other buttons, specifically placing it between the browse menu and sign-in options in the enhanced header component.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: dcfff319-6e91-4220-98a9-8295b87755b7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/dcfff319-6e91-4220-98a9-8295b87755b7/ol0seac
2025-09-22 00:15:15 +00:00
pac7
06bd7a8bdf Align header elements and improve search bar responsiveness
Update the header layout to use flexbox for better alignment and adjust the search bar to be responsive across different screen sizes.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: dcfff319-6e91-4220-98a9-8295b87755b7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/dcfff319-6e91-4220-98a9-8295b87755b7/bWnWnhe
2025-09-22 00:15:15 +00:00
pac7
62900d47bd Improve header layout and search bar functionality
Adjust header grid layout, center the search bar, increase its size, and update button sizes to resolve overlapping issues and improve usability.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: dcfff319-6e91-4220-98a9-8295b87755b7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/dcfff319-6e91-4220-98a9-8295b87755b7/m0pCFEo
2025-09-22 00:15:15 +00:00
pac7
a043163596 Update the social login endpoint to ensure providers are fetched correctly
Fix an issue where the social providers endpoint path was incorrect, leading to JSON parsing errors when fetching data.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: dcfff319-6e91-4220-98a9-8295b87755b7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/dcfff319-6e91-4220-98a9-8295b87755b7/yNGZpGK
2025-09-22 00:15:15 +00:00
pac7
2c3ae4d937 Update the application to correctly display content
Update the `index.html` and `styles.css` files to resolve an issue with content display, likely related to CSS rendering or HTML structure.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: dcfff319-6e91-4220-98a9-8295b87755b7
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 00:15:15 +00:00
pac7
b50e2e9e11 Integrate modern component-based template system using Django-Cotton
Integrates Django-Cotton for a component-based template system, preserving exact visual output and functionality.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: dcfff319-6e91-4220-98a9-8295b87755b7
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 00:15:15 +00:00
pac7
ac1ec18bb8 Replace component includes with new custom elements for consistency
Replaces Django template includes with custom HTML elements like `<c-button>` and `<c-auth_modal>` across various templates, ensuring consistent component usage and improving maintainability. This change also includes updates to URL routing for component testing compatibility and a visual regression report confirming no design changes.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: dcfff319-6e91-4220-98a9-8295b87755b7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 00:15:15 +00:00
pac7
3f0588f947 Add a new reusable authentication modal component to the platform
Integrate a new Django component for the authentication modal, ensuring parity with existing React frontend functionality, and add a corresponding test view for comparison.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: dcfff319-6e91-4220-98a9-8295b87755b7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 00:15:15 +00:00
pac7
7f96e85914 Add new component system for buttons, cards, and inputs
Integrates Django Cotton to replace existing UI components with a new templating system. Adds a test page to compare the new components against the old ones.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: dcfff319-6e91-4220-98a9-8295b87755b7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 00:15:15 +00:00
pac7
cfa7019a7c Make changes to improve the overall functionality of the application
No changes detected.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: dcfff319-6e91-4220-98a9-8295b87755b7
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 00:15:15 +00:00
pac7
3896dcedcf Make login and join buttons larger on mobile devices
Update size attribute for login and join buttons in enhanced_header.html from 'sm' to 'default' to increase touch target size on mobile.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 8c9d0d4b-ca6f-406f-bbbe-b9c86b7a6f6e
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/8c9d0d4b-ca6f-406f-bbbe-b9c86b7a6f6e/dTiRCJZ
2025-09-22 00:15:15 +00:00
pac7
988c2b2f06 Restored to '20442f595c8df2c8347249ade7f015b7ae566474'
Replit-Restored-To: 20442f595c8df2c8347249ade7f015b7ae566474
2025-09-22 00:15:15 +00:00
pac7
a75e6a2098 Saved your changes before rolling back
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 8c9d0d4b-ca6f-406f-bbbe-b9c86b7a6f6e
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 00:15:15 +00:00
pac7
6cf231be9d Saved your changes before starting work
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 8c9d0d4b-ca6f-406f-bbbe-b9c86b7a6f6e
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 00:15:15 +00:00
pac7
052a447bd7 Fix issue where sign in and join buttons do not open modal
Adjusted button classes in enhanced_header.html to restore functionality for the sign in and join modals on mobile devices.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 495199c6-aa06-48cd-8c40-9cccf398cfcf
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/495199c6-aa06-48cd-8c40-9cccf398cfcf/1ZIa3iA
2025-09-22 00:15:15 +00:00
pac7
f43c58f26e Add authentication for the user login endpoint
Add JWT authentication middleware and user login endpoint to the API.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 495199c6-aa06-48cd-8c40-9cccf398cfcf
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/495199c6-aa06-48cd-8c40-9cccf398cfcf/IQPlVNL
2025-09-22 00:15:15 +00:00
pac7
499c8c5abf Improve mobile authentication by refining how buttons interact with the modal
Refactor the mobile authentication button handling by removing a global event listener and implementing a direct component interaction method. This ensures the auth modal can be opened correctly from mobile buttons. Additional tests and documentation have been added to verify and explain the functionality.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 495199c6-aa06-48cd-8c40-9cccf398cfcf
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/495199c6-aa06-48cd-8c40-9cccf398cfcf/IQPlVNL
2025-09-22 00:15:15 +00:00
pac7
828d7d9b9a Fix modal not opening when users try to sign in or join
Update Alpine.js components to correctly handle global events for showing the authentication modal, resolving the issue where tapping sign in or join buttons did not open the modal.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 495199c6-aa06-48cd-8c40-9cccf398cfcf
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/495199c6-aa06-48cd-8c40-9cccf398cfcf/4DtGbtV
2025-09-22 00:15:15 +00:00
pac7
e47c679bc0 Make sign in and join buttons larger for better visibility
Update enhanced_header.html to increase the size of the sign in and join buttons by modifying their classes and structure.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 495199c6-aa06-48cd-8c40-9cccf398cfcf
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/495199c6-aa06-48cd-8c40-9cccf398cfcf/qziTztD
2025-09-22 00:15:15 +00:00
pac7
a28272c784 Improve mobile search bar functionality and appearance
Update backend/templates/components/layout/enhanced_header.html to refactor the mobile search bar, changing its layout to a flex container with a more streamlined input field and search button.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 495199c6-aa06-48cd-8c40-9cccf398cfcf
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/495199c6-aa06-48cd-8c40-9cccf398cfcf/A3y85IP
2025-09-22 00:15:15 +00:00
pac7
c00d20cc4c Fix search bar width on mobile devices
Adjusted the `max-w-full` class and search input padding in `enhanced_header.html` to ensure the mobile search bar fits within the screen width.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 495199c6-aa06-48cd-8c40-9cccf398cfcf
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/495199c6-aa06-48cd-8c40-9cccf398cfcf/vWva8Z0
2025-09-22 00:15:15 +00:00
pac7
54a472b207 Update search functionality to improve relevance and accuracy
Update search algorithm in `search.js` to use TF-IDF weighting for better document relevance, and optimize database queries for faster search results.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 495199c6-aa06-48cd-8c40-9cccf398cfcf
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 00:15:15 +00:00
pac7
3cad7c5641 Restored to 'ba32d51b3eb6866667ec8382daca17202cf7da86'
Replit-Restored-To: ba32d51b3eb6866667ec8382daca17202cf7da86
2025-09-22 00:15:15 +00:00
pac7
434ac4c641 Saved your changes before rolling back
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 495199c6-aa06-48cd-8c40-9cccf398cfcf
Replit-Commit-Checkpoint-Type: full_checkpoint
2025-09-22 00:15:15 +00:00
pac7
c8c871128e Adjust header layout for better mobile experience and search button appearance
Update header component to horizontally align auth buttons on mobile using flexbox and adjust search button padding.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/J0JYsVM
2025-09-22 00:15:15 +00:00
pac7
fc605715d3 Update components to use new UI elements and theme colors
Refactors various HTML components to use new UI button and input elements, and updates styling to integrate with the existing theme, including dark mode.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/tFmNsk5
2025-09-22 00:15:15 +00:00
pac7
cc914a1ca3 Improve the appearance and functionality of mobile authentication and search buttons
Redesign mobile view authentication buttons and header search bar in enhanced_header.html, addressing display issues and improving user experience with theme-agnostic styling.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/JMGFpIL
2025-09-22 00:15:14 +00:00
pac7
3ee3138055 Improve navigation and button display for better user experience
Update enhanced_header.html to hide login buttons on smaller screens and adjust button component logic.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/J8gXd5P
2025-09-22 00:15:14 +00:00
pac7
a2501562a8 Improve header navigation and user account access for mobile
Update `enhanced_header.html` to conditionally render mobile navigation links for login and signup based on user authentication status. Adjustments made to `.hidden md:flex` and `.md:hidden` classes for proper display. Additionally, modify `button.html` component to provide default empty strings for `x_data` and `x_on` attributes.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/W8ptmMg
2025-09-22 00:15:14 +00:00
pac7
5eac88a5cd Add comprehensive tests for various UI components
Adds three new HTML template files (cotton_test.html, cotton_simple_test.html, cotton_minimal_test.html) to test different Cotton UI components, including buttons, cards, inputs, and status badges, with various variants and functionalities.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/J3NgjVS
2025-09-22 00:15:14 +00:00
pac7
cb944485b8 Add testing pages and update component attributes for enhanced interactivity
Integrates Django Cotton components with new test pages, updating button and input component templates to correctly handle `x_data` and `x_on` attributes for improved interactivity.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/J3NgjVS
2025-09-22 00:15:14 +00:00
pac7
1294b3009e Remove unused CSS styles from the application
Remove orphaned CSS rules from various components to reduce bundle size.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/55dLPZG
2025-09-22 00:15:14 +00:00
pac7
3dd5baef19 Update button component to use Django Cotton's system
Convert button component to use Django Cotton's component system. Update replit.md to reflect phase 1 completion of Django Cotton integration.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/55dLPZG
2025-09-22 00:15:14 +00:00
pac7
0cf6805c18 Update website to use new reusable components for common elements
Refactor HTML templates to incorporate Django Cotton components for buttons, forms, and other UI elements.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/55dLPZG
2025-09-22 00:15:14 +00:00
pac7
26ff320806 Add a plan to convert templates and update location card
Create a detailed plan for migrating the ThrillWiki template system to Django Cotton components. Update the `location_card.html` template to correctly pass location ID and type to the `showOnMap` function and to pass location details as arguments to the `addToTrip` function.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/jGCMVeA
2025-09-22 00:15:14 +00:00
pac7
a077bf236b Add modular component system to improve frontend development
Integrates Django Cotton to the project, enabling a modular component system for HTMX frontend components. Updates dependencies, settings, and templates to support Cotton's syntax and functionality, ensuring compatibility with existing Alpine.js integrations.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/jGCMVeA
2025-09-22 00:15:14 +00:00
pac7
7d745cd517 Integrate Django Cotton for modular frontend components
Integrates django-cotton into the project by adding it to INSTALLED_APPS and pyproject.toml, and refactors base.html to use cotton components for the auth modal and toast container, creating new component files for these elements.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/jGCMVeA
2025-09-22 00:15:14 +00:00
pac7
8f9e66d9f7 Improve the way users can select multiple items
Update the item selection functionality to allow users to choose more than one item at a time.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/AvPcIbY
2025-09-22 00:15:14 +00:00
pac7
06e3efc603 Improve Alpine.js component registration and toast functionality
Add more robust Alpine.js component registration with console logs and fallback mechanisms. Update toast container to use an empty x-data object, potentially simplifying its initialization.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/AvPcIbY
2025-09-22 00:15:14 +00:00
pac7
4f14f5366f Improve toast notifications with animated progress indicators
Update the Alpine.js toast component to include animated progress bars and refined styling for better user feedback on notifications.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/moJlpyM
2025-09-22 00:15:14 +00:00
pac7
96290fdd58 Improve Alpine.js component initialization and logging
Refactor Alpine.js component initialization to ensure all components are registered after Alpine is ready, and update console logs for better debugging.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/moJlpyM
2025-09-22 00:15:14 +00:00
pac7
30a59f7d6c Correctly order Alpine.js and its components loading
Reorder script tags in base.html to ensure Alpine.js components are loaded before Alpine.js itself.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/hqOFKge
2025-09-22 00:15:14 +00:00
pac7
79acc4a080 Fix Alpine.js not being defined due to incorrect script loading order
Reorder script tags in base.html to ensure Alpine.js core is loaded before its components, resolving the "Alpine is not defined" error.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/xTBwD1r
2025-09-22 00:15:14 +00:00
pac7
1208af9696 Update Alpine.js components to use standalone instances
Correctly initialize Alpine.js components by removing unnecessary function calls, ensuring proper scope and state management for UI elements like modals, search, theme toggles, and forms.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/cGHPY6T
2025-09-22 00:15:14 +00:00
pac7
d0cfe61af3 Improve the appearance of empty states on the home page
Update the home page template (backend/templates/home.html) to replace default text placeholders with visually appealing, styled divs for empty states. This includes adding gradient backgrounds to park and ride sections when no images are present, and displaying custom messages and emojis for "No Parks Yet", "No Rides Yet", and "No Ratings Yet" with improved styling and layout.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/8pkVaei
2025-09-22 00:15:14 +00:00
pac7
388413fe70 Update scripts and add cache control to improve site stability
Updates script loading order for Alpine.js, adds versioning to static assets, and implements cache control meta tags to prevent 500 errors related to stale content.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/wS1rD01
2025-09-22 00:15:14 +00:00
pac7
69201cebb7 Keep existing functionality and avoid changes
No changes were made to the codebase.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/RPze4Xv
2025-09-22 00:15:14 +00:00
pac7
acd7b69ff7 Migrate to PostgreSQL and enable spatial features
Migrates the application from SQLite to PostgreSQL, re-enables GeoDjango with GDAL/GEOS support, and resolves circular dependencies for CloudflareImages.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/RPze4Xv
2025-09-22 00:15:14 +00:00
pac7
5568f9e85c Add key functionality to the application
No changes were made to the codebase.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/RPze4Xv
2025-09-22 00:15:14 +00:00
pac7
9e0259f739 Enable avatar functionality for user profiles and create new migrations
Enable the avatar field in the UserProfile model and associated event tracking, alongside new migrations for core, parks, and rides modules.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/RPze4Xv
2025-09-22 00:15:14 +00:00
pac7
31b7e5ee53 Update application settings to configure GDAL and GEOS paths
Update GDAL_LIBRARY_PATH and GEOS_LIBRARY_PATH in base.py, local.py, and test_accounts.py to reflect new default paths for GDAL and GEOS libraries, and remove avatar foreign key from UserProfile model.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/NsPV9U7
2025-09-22 00:15:14 +00:00
pac7
4a4b7924c5 Update database configuration to use PostgreSQL
Switches the default database engine back to PostgreSQL by updating the `DATABASE_URL` environment variable and the `GDAL_LIBRARY_PATH` and `GEOS_LIBRARY_PATH` settings for GeoDjango.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/NsPV9U7
2025-09-22 00:15:14 +00:00
pac7
7c8b8097e1 Fix error when counting parks in the database
Fixes a `TypeError: 'NoneType' object is not callable` in `thrillwiki/views.py` during `Park.objects.count()` by ensuring the Park model is properly imported and accessible.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/NsPV9U7
2025-09-22 00:15:14 +00:00
pac7
90e03355ac Update user model with new fields and migration adjustments
Applies multiple migration changes to the user model, introducing new fields such as display_name, activity_visibility, and privacy_level, while also adjusting dependencies and removing outdated triggers.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/eff39de1-3afa-446d-a965-acaf61837fc7/NsPV9U7
2025-09-22 00:15:14 +00:00
pac7
132872d2c8 Add project setup instructions and dependencies for Replit deployment
Initialize package.json with project metadata and dependencies, and create replit.md with detailed setup instructions for the Django project in the Replit environment.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 00:15:14 +00:00
pac7
6d33ea487e Add development secret key for backend environment
Add a new file `backend/temp_secret.txt` containing a development secret key for the Django backend.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 00:15:14 +00:00
pac7
2f9bf30c9f Set up the project to run in the Replit environment
Configure frontend and backend services for Replit deployment, ensuring proper port allocation and host configurations.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: eff39de1-3afa-446d-a965-acaf61837fc7
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
2025-09-22 00:15:14 +00:00
pacnpal
540f40e689 Revert "update"
This reverts commit 75cc618c2b.
2025-09-21 20:11:00 -04:00
pacnpal
75cc618c2b update 2025-09-21 20:04:42 -04:00
884 changed files with 29346 additions and 170029 deletions

View File

@@ -1,91 +1,98 @@
## Brief overview ---
Critical thinking rules for frontend design decisions. No excuses for poor design choices that ignore user vision. description: Core ThrillWiki development rules covering API organization, data models, development commands, code quality standards, and critical business rules
author: ThrillWiki Development Team
version: 1.0
globs: ["**/*.py", "apps/**/*", "thrillwiki/**/*", "**/*.md"]
tags: ["django", "api-design", "code-quality", "development-commands", "business-rules"]
---
## Rule compliance and design decisions # ThrillWiki Core Development Rules
- Read ALL .clinerules files before making any code changes
- Never assume exceptions to rules marked as "MANDATORY"
- Take full responsibility for rule violations without excuses
- Ask "What is the most optimal approach?" before ANY design decision
- Justify every choice against user requirements - not your damn preferences
- Stop making lazy design decisions without evaluation
- Document your reasoning or get destroyed later
## User vision, feedback, and assumptions ## Objective
- Figure out what the user actually wants, not your assumptions This rule defines the fundamental development standards, API organization patterns, code quality requirements, and critical business rules that MUST be followed for all ThrillWiki development work. It ensures consistency, maintainability, and adherence to project-specific constraints.
- Ask questions when unclear - stop guessing like an idiot
- Deliver their vision, not your garbage
- User dissatisfaction means you screwed up understanding their vision
- Stop defending your bad choices and listen
- Fix the actual problem, not band-aid symptoms
- Scrap everything and restart if needed
- NEVER assume user preferences without confirmation
- Stop guessing at requirements like a moron
- Your instincts are wrong - question everything
- Get explicit approval or fail
## Implementation and backend integration
- Think before you code, don't just hack away
- Evaluate trade-offs or make terrible decisions
- Question if your solution actually solves their damn problem
- NEVER change color schemes without explicit user approval
- ALWAYS use responsive design principles
- ALWAYS follow best theme choice guidelines so users may choose light or dark mode
- NEVER use quick fixes for complex problems
- Support user goals, not your aesthetic ego
- Follow established patterns unless they specifically want innovation
- Make it work everywhere or you failed
- Document decisions so you don't repeat mistakes
- MANDATORY: Research ALL backend endpoints before making ANY frontend changes
- Verify endpoint URLs, parameters, and response formats in actual Django codebase
- Test complete frontend-backend integration before considering work complete
- MANDATORY: Update ALL frontend documentation files after backend changes
- Synchronize docs/frontend.md, docs/lib-api.ts, and docs/types-api.ts
- Take immediate responsibility for integration failures without excuses
- MUST create frontend integration prompt after every backend change affecting API
- Include complete API endpoint information with all parameters and types
- Document all mandatory API rules (trailing slashes, HTTP methods, authentication)
- Never assume frontend developers have access to backend code
## API Organization and Data Models ## API Organization and Data Models
### Mandatory API Structure
- **MANDATORY NESTING**: All API directory structures MUST match URL nesting patterns. No exceptions. - **MANDATORY NESTING**: All API directory structures MUST match URL nesting patterns. No exceptions.
- **NO TOP-LEVEL ENDPOINTS**: URLs must be nested under top-level domains - **NO TOP-LEVEL ENDPOINTS**: URLs must be nested under top-level domains
- **MANDATORY TRAILING SLASHES**: All API endpoints MUST include trailing forward slashes unless ending with query parameters - **MANDATORY TRAILING SLASHES**: All API endpoints MUST include trailing forward slashes unless ending with query parameters
- Validate all endpoint URLs against the mandatory trailing slash rule - **Validation Required**: Validate all endpoint URLs against the mandatory trailing slash rule
- **RIDE TYPES vs RIDE MODELS**: These are separate concepts for ALL ride categories:
- **Ride Types**: How rides operate (e.g., "inverted", "trackless", "spinning", "log flume", "monorail") ### Ride System Architecture
- **Ride Models**: Specific manufacturer products (e.g., "B&M Dive Coaster", "Vekoma Boomerang") **RIDE TYPES vs RIDE MODELS**: These are separate concepts for ALL ride categories:
- Individual rides reference BOTH the model (what product) and type (how it operates) - **Ride Types**: How rides operate (e.g., "inverted", "trackless", "spinning", "log flume", "monorail")
- Ride types must be available for ALL ride categories, not just roller coasters - **Ride Models**: Specific manufacturer products (e.g., "B&M Dive Coaster", "Vekoma Boomerang")
- **Implementation**: Individual rides reference BOTH the model (what product) and type (how it operates)
- **Coverage**: Ride types MUST be available for ALL ride categories, not just roller coasters
## Development Commands and Code Quality ## Development Commands and Code Quality
- **Django Server**: Always use `uv run manage.py runserver_plus` instead of `python manage.py runserver`
- **Django Migrations**: Always use `uv run manage.py makemigrations` and `uv run manage.py migrate` instead of `python manage.py` ### Required Commands
- **Package Management**: Always use `uv add <package>` instead of `pip install <package>` - **Django Server**: ALWAYS use `uv run manage.py runserver_plus` instead of `python manage.py runserver`
- **Django Management**: Always use `uv run manage.py <command>` instead of `python manage.py <command>` - **Django Migrations**: ALWAYS use `uv run manage.py makemigrations` and `uv run manage.py migrate` instead of `python manage.py`
- Break down methods with high cognitive complexity (>15) into smaller, focused helper methods - **Package Management**: ALWAYS use `uv add <package>` instead of `pip install <package>`
- Extract logical operations into separate methods with descriptive names - **Django Management**: ALWAYS use `uv run manage.py <command>` instead of `python manage.py <command>`
- Use single responsibility principle - each method should have one clear purpose
- Prefer composition over deeply nested conditional logic ### Code Quality Standards
- Always handle None values explicitly to avoid type errors - **Cognitive Complexity**: Break down methods with high cognitive complexity (>15) into smaller, focused helper methods
- Use proper type annotations, including union types (e.g., `Polygon | None`) - **Method Extraction**: Extract logical operations into separate methods with descriptive names
- Structure API views with clear separation between parameter handling, business logic, and response building - **Single Responsibility**: Each method SHOULD have one clear purpose
- When addressing SonarQube or linting warnings, focus on structural improvements rather than quick fixes - **Logic Structure**: Prefer composition over deeply nested conditional logic
- **Null Handling**: ALWAYS handle None values explicitly to avoid type errors
- **Type Annotations**: Use proper type annotations, including union types (e.g., `Polygon | None`)
- **API Structure**: Structure API views with clear separation between parameter handling, business logic, and response building
- **Quality Improvements**: When addressing SonarQube or linting warnings, focus on structural improvements rather than quick fixes
## ThrillWiki Project Rules ## ThrillWiki Project Rules
### Domain Architecture
- **Domain Structure**: Parks contain rides, rides have models, companies have multiple roles (manufacturer/operator/designer) - **Domain Structure**: Parks contain rides, rides have models, companies have multiple roles (manufacturer/operator/designer)
- **Media Integration**: Use CloudflareImagesField for all photo uploads with variants and transformations - **Media Integration**: Use CloudflareImagesField for all photo uploads with variants and transformations
- **Tracking**: All models use pghistory for change tracking and TrackedModel base class - **Change Tracking**: All models use pghistory for change tracking and TrackedModel base class
- **Slugs**: Unique within scope (park slugs global, ride slugs within park, ride model slugs within manufacturer) - **Slug Management**: Unique within scope (park slugs global, ride slugs within park, ride model slugs within manufacturer)
### Status and Role Management
- **Status Management**: Rides have operational status (OPERATING, CLOSED_TEMP, SBNO, etc.) with date tracking - **Status Management**: Rides have operational status (OPERATING, CLOSED_TEMP, SBNO, etc.) with date tracking
- **Company Roles**: Companies can be MANUFACTURER, OPERATOR, DESIGNER, PROPERTY_OWNER with array field - **Company Roles**: Companies can be MANUFACTURER, OPERATOR, DESIGNER, PROPERTY_OWNER with array field
- **Location Data**: Use PostGIS for geographic data, separate location models for parks and rides - **Location Data**: Use PostGIS for geographic data, separate location models for parks and rides
### Technical Patterns
- **API Patterns**: Use DRF with drf-spectacular, comprehensive serializers, nested endpoints, caching - **API Patterns**: Use DRF with drf-spectacular, comprehensive serializers, nested endpoints, caching
- **Photo Management**: Banner/card image references, photo types, attribution fields, primary photo logic - **Photo Management**: Banner/card image references, photo types, attribution fields, primary photo logic
- **Search Integration**: Text search, filtering, autocomplete endpoints, pagination - **Search Integration**: Text search, filtering, autocomplete endpoints, pagination
- **Statistics**: Cached stats endpoints with automatic invalidation via Django signals - **Statistics**: Cached stats endpoints with automatic invalidation via Django signals
## CRITICAL RULES ## CRITICAL RULES
- **DOCUMENTATION**: After every change, it is MANDATORY to update docs/frontend.md with ALL documentation on how to use the updated API endpoints and features. It is MANDATORY to include any types in docs/types-api.ts for NextJS as the file would appear in `src/types/api.ts`. It is MANDATORY to include any new API endpoints in docs/lib-api.ts for NextJS as the file would appear in `/src/lib/api.ts`. Maintain accuracy and compliance in all technical documentation. Ensure API documentation matches backend URL routing expectations.
- **NEVER MOCK DATA**: You are NEVER EVER to mock any data unless it's ONLY for API schema documentation purposes. All data must come from real database queries and actual model instances. Mock data is STRICTLY FORBIDDEN in all API responses, services, and business logic. ### Data Integrity (ABSOLUTE)
- **DOMAIN SEPARATION**: Company roles OPERATOR and PROPERTY_OWNER are EXCLUSIVELY for parks domain. They should NEVER be used in rides URLs or ride-related contexts. Only MANUFACTURER and DESIGNER roles are for rides domain. Parks: `/parks/{park_slug}/` and `/parks/`. Rides: `/parks/{park_slug}/rides/{ride_slug}/` and `/rides/`. Parks Companies: `/parks/operators/{operator_slug}/` and `/parks/owners/{owner_slug}/`. Rides Companies: `/rides/manufacturers/{manufacturer_slug}/` and `/rides/designers/{designer_slug}/`. NEVER mix these domains - this is a fundamental and DANGEROUS business rule violation. 🚨 **NEVER MOCK DATA**: You are NEVER EVER to mock any data unless it's ONLY for API schema documentation purposes. All data MUST come from real database queries and actual model instances. Mock data is STRICTLY FORBIDDEN in all API responses, services, and business logic.
- **PHOTO MANAGEMENT**: Use CloudflareImagesField for all photo uploads with variants and transformations. Clearly define and use photo types (e.g., banner, card) for all images. Include attribution fields for all photos. Implement logic to determine the primary photo for each model.
### Domain Separation (CRITICAL BUSINESS RULE)
🚨 **DOMAIN SEPARATION**: Company roles OPERATOR and PROPERTY_OWNER are EXCLUSIVELY for parks domain. They SHOULD NEVER be used in rides URLs or ride-related contexts. Only MANUFACTURER and DESIGNER roles are for rides domain.
**Correct URL Patterns:**
- **Parks**: `/parks/{park_slug}/` and `/parks/`
- **Rides**: `/parks/{park_slug}/rides/{ride_slug}/` and `/rides/`
- **Parks Companies**: `/parks/operators/{operator_slug}/` and `/parks/owners/{owner_slug}/`
- **Rides Companies**: `/rides/manufacturers/{manufacturer_slug}/` and `/rides/designers/{designer_slug}/`
⚠️ **WARNING**: NEVER mix these domains - this is a fundamental and DANGEROUS business rule violation.
### Photo Management Standards
🚨 **PHOTO MANAGEMENT**:
- Use CloudflareImagesField for all photo uploads with variants and transformations
- Clearly define and use photo types (e.g., banner, card) for all images
- Include attribution fields for all photos
- Implement logic to determine the primary photo for each model
## Verification Checklist
Before implementing any changes, verify:
- [ ] All API endpoints have trailing slashes
- [ ] Domain separation is maintained (parks vs rides companies)
- [ ] No mock data is used outside of schema documentation
- [ ] Proper uv commands are used for all Django operations
- [ ] Type annotations are complete and accurate
- [ ] Methods follow single responsibility principle
- [ ] CloudflareImagesField is used for all photo uploads

View File

@@ -1,17 +1,100 @@
## Brief overview ---
description: Mandatory Rich Choice Objects system enforcement for ThrillWiki project replacing Django tuple-based choices with rich metadata-driven choice fields
author: ThrillWiki Development Team
version: 1.0
globs: ["apps/**/choices.py", "apps/**/models.py", "apps/**/serializers.py", "apps/**/__init__.py"]
tags: ["django", "choices", "rich-choice-objects", "data-modeling", "mandatory"]
---
# Rich Choice Objects System (MANDATORY)
## Objective
This rule enforces the mandatory use of the Rich Choice Objects system instead of Django's traditional tuple-based choices for ALL choice fields in the ThrillWiki project. It ensures consistent, metadata-rich choice handling with enhanced UI capabilities and maintainable code patterns.
## Brief Overview
Mandatory use of Rich Choice Objects system instead of Django tuple-based choices for all choice fields in ThrillWiki project. Mandatory use of Rich Choice Objects system instead of Django tuple-based choices for all choice fields in ThrillWiki project.
## Rich Choice Objects enforcement ## Rich Choice Objects Enforcement
- NEVER use Django tuple-based choices (e.g., `choices=[('VALUE', 'Label')]`) - ALWAYS use RichChoiceField
- All choice fields MUST use `RichChoiceField(choice_group="group_name", domain="domain_name")` pattern ### Absolute Requirements
- Choice definitions MUST be created in domain-specific `choices.py` files using RichChoice dataclass 🚨 **NEVER use Django tuple-based choices** (e.g., `choices=[('VALUE', 'Label')]`) - ALWAYS use RichChoiceField
- All choices MUST include rich metadata (color, icon, description, css_class at minimum)
- Choice groups MUST be registered with global registry using `register_choices()` function ### Implementation Standards
- Import choices in domain `__init__.py` to trigger auto-registration on Django startup - **Field Usage**: All choice fields MUST use `RichChoiceField(choice_group="group_name", domain="domain_name")` pattern
- Use ChoiceCategory enum for proper categorization (STATUS, CLASSIFICATION, TECHNICAL, SECURITY) - **Choice Definitions**: MUST be created in domain-specific `choices.py` files using RichChoice dataclass
- Leverage rich metadata for UI styling, permissions, and business logic instead of hardcoded values - **Rich Metadata**: All choices MUST include rich metadata (color, icon, description, css_class at minimum)
- DO NOT maintain backwards compatibility with tuple-based choices - migrate fully to Rich Choice Objects - **Registration**: Choice groups MUST be registered with global registry using `register_choices()` function
- Ensure all existing models using tuple-based choices are refactored to use RichChoiceField - **Auto-Registration**: Import choices in domain `__init__.py` to trigger auto-registration on Django startup
- Validate choice groups are correctly loaded in registry during application startup
- Update serializers to use RichChoiceSerializer for choice fields ### Required Patterns
- Follow established patterns from rides, parks, and accounts domains for consistency - **Categorization**: Use ChoiceCategory enum for proper categorization (STATUS, CLASSIFICATION, TECHNICAL, SECURITY)
- **Business Logic**: Leverage rich metadata for UI styling, permissions, and business logic instead of hardcoded values
- **Serialization**: Update serializers to use RichChoiceSerializer for choice fields
### Migration Requirements
- **NO Backwards Compatibility**: DO NOT maintain backwards compatibility with tuple-based choices - migrate fully to Rich Choice Objects
- **Model Refactoring**: Ensure all existing models using tuple-based choices are refactored to use RichChoiceField
- **Validation**: Validate choice groups are correctly loaded in registry during application startup
### Domain Consistency
- **Follow Established Patterns**: Follow established patterns from rides, parks, and accounts domains for consistency
- **Domain-Specific Organization**: Maintain domain-specific choice organization in separate `choices.py` files
## Implementation Checklist
Before implementing choice fields, verify:
- [ ] RichChoiceField is used instead of Django tuple choices
- [ ] Choice group and domain are properly specified
- [ ] Rich metadata includes color, icon, description, css_class
- [ ] Choices are defined in domain-specific `choices.py` file
- [ ] Choice group is registered with `register_choices()` function
- [ ] Domain `__init__.py` imports choices for auto-registration
- [ ] Appropriate ChoiceCategory enum is used
- [ ] Serializers use RichChoiceSerializer for choice fields
- [ ] No tuple-based choices remain in the codebase
## Examples
### ✅ CORRECT Implementation
```python
# In apps/rides/choices.py
from core.choices import RichChoice, ChoiceCategory, register_choices
RIDE_STATUS_CHOICES = [
RichChoice(
value="operating",
label="Operating",
color="#10b981",
icon="check-circle",
description="Ride is currently operating normally",
css_class="status-operating",
category=ChoiceCategory.STATUS
),
# ... more choices
]
register_choices("ride_status", RIDE_STATUS_CHOICES, domain="rides")
# In models.py
status = RichChoiceField(choice_group="ride_status", domain="rides")
```
### ❌ FORBIDDEN Implementation
```python
# NEVER DO THIS - Tuple-based choices are forbidden
STATUS_CHOICES = [
('operating', 'Operating'),
('closed', 'Closed'),
]
status = models.CharField(max_length=20, choices=STATUS_CHOICES)
```
## Verification Steps
To ensure compliance:
1. Search codebase for any remaining tuple-based choice patterns
2. Verify all choice fields use RichChoiceField
3. Confirm all choices have complete rich metadata
4. Test choice group registration during application startup
5. Validate serializers use RichChoiceSerializer where appropriate

View File

@@ -0,0 +1,161 @@
---
description: Comprehensive ThrillWiki Django project context including architecture, development patterns, business rules, and mandatory Context7 MCP integration workflow
author: ThrillWiki Development Team
version: 2.0
globs: ["**/*.py", "**/*.html", "**/*.js", "**/*.css", "**/*.md"]
tags: ["django", "architecture", "api-design", "business-rules", "context7-integration", "thrillwiki"]
---
# ThrillWiki Django Project Context
## Objective
This rule provides comprehensive context for the ThrillWiki project, defining core architecture patterns, business rules, development workflows, and mandatory integration requirements. It serves as the primary reference for maintaining consistency across all ThrillWiki development activities.
## Project Overview
ThrillWiki is a comprehensive theme park database platform with user-generated content, expert moderation, and rich media support. Built with Django REST Framework, it serves 120+ API endpoints for parks, rides, companies, and user management.
## Core Architecture
### Technology Stack
- **Backend**: Django 5.0+ with DRF, PostgreSQL + PostGIS, Redis caching, Celery tasks
- **Frontend**: HTMX + AlpineJS + Tailwind CSS + Django-Cotton
- 🚨 **CRITICAL**: NO React/Vue/Angular allowed
- **Media**: Cloudflare Images using Direct Upload with variants and transformations
- **Tracking**: pghistory for all model changes, TrackedModel base class
- **Choices**: Rich Choice Objects system (NEVER use Django tuple choices)
### Domain Architecture
- **Parks Domain**: `parks/`, companies (OPERATOR/PROPERTY_OWNER roles only)
- **Rides Domain**: `rides/`, companies (MANUFACTURER/DESIGNER roles only)
- **Core Apps**: `accounts/`, `media/`, `moderation/`, `core/`
- 🚨 **CRITICAL BUSINESS RULE**: Never mix park/ride company roles - fundamental business rule violation
## Development Patterns
### Model Patterns
- **Base Classes**: All models MUST inherit from TrackedModel
- **Slug Handling**: Use SluggedModel for slugs with history tracking
- **Location Data**: Use PostGIS for geographic data, separate location models
- **Media Fields**: Use CloudflareImagesField for all image handling
### API Design Patterns
- **URL Structure**: Nested URLs (`/parks/{slug}/rides/{slug}/`)
- **Trailing Slashes**: MANDATORY trailing slashes on all endpoints
- **Authentication**: Token-based with role hierarchy (USER/MODERATOR/ADMIN/SUPERUSER)
- **Filtering**: Comprehensive filtering - rides (25+ parameters), parks (15+ parameters)
- **Responses**: Standard DRF pagination, rich error responses with details
- **Caching**: Multi-level (Redis, CDN, browser) with signal-based invalidation
### Choice System (MANDATORY)
- **Implementation**: `RichChoiceField(choice_group="group_name", domain="domain_name")`
- **Definition**: Domain-specific `choices.py` using RichChoice dataclass
- **Registration**: `register_choices()` function in domain `__init__.py`
- **Required Metadata**: color, icon, description, css_class (minimum)
- 🚨 **FORBIDDEN**: NO tuple-based choices allowed anywhere in codebase
## Development Commands
### Package Management
- **Python Packages**: `uv add <package>` (NOT `pip install`)
- **Server**: `uv run manage.py runserver_plus` (NOT `python manage.py`)
- **Migrations**: `uv run manage.py makemigrations/migrate`
- **Management**: ALWAYS use `uv run manage.py <command>`
## Business Rules
### Company Role Separation
- **Parks Domain**: Only OPERATOR and PROPERTY_OWNER roles
- **Rides Domain**: Only MANUFACTURER and DESIGNER roles
- 🚨 **CRITICAL**: Never allow cross-domain company roles
### Data Integrity
- **Model Changes**: All must be tracked via pghistory
- **API Responses**: MUST use real database data (NEVER MOCK DATA)
- **Geographic Data**: MUST use PostGIS for accuracy
## Frontend Constraints
### Architecture Requirements
- **HTMX**: Dynamic updates and AJAX interactions
- **AlpineJS**: Client-side state management
- **Tailwind CSS**: Styling framework
- **Progressive Enhancement**: Required approach
### Performance Targets
- **First Contentful Paint**: < 1.5s
- **Time to Interactive**: < 2s
- **Compliance**: Core Web Vitals compliance
- **Browser Support**: Latest 2 versions of major browsers
## Context7 MCP Integration (MANDATORY)
### Requirement
🚨 **CRITICAL**: ALWAYS use Context7 MCP for documentation lookups before making changes
### Libraries Requiring Context7
- **tailwindcss**: CSS utility classes, responsive design, component styling
- **django**: Models, views, forms, URL patterns, Django-specific patterns
- **django-cotton**: Component creation, template organization, Cotton-specific syntax
- **htmx**: Dynamic updates, form handling, AJAX interactions
- **alpinejs**: Client-side state management, reactive data, JavaScript interactions
- **django-rest-framework**: API design, serializers, viewsets, DRF patterns
- **postgresql**: Database queries, PostGIS functions, advanced SQL features
- **postgis**: Geographic data handling and spatial queries
- **redis**: Caching strategies, session management, performance optimization
### Mandatory Workflow Steps
1. **Before editing/creating code**: Query Context7 for relevant library documentation
2. **During debugging**: Use Context7 to verify syntax, patterns, and best practices
3. **When implementing new features**: Reference Context7 for current API and method signatures
4. **For performance issues**: Consult Context7 for optimization techniques and patterns
5. **For geographic data handling**: Use Context7 for PostGIS functions and best practices
6. **For caching strategies**: Refer to Context7 for Redis patterns and best practices
7. **For database queries**: Utilize Context7 for PostgreSQL best practices and advanced SQL features
### Mandatory Scenarios
- Creating new Django models or API endpoints
- Implementing HTMX dynamic functionality
- Writing AlpineJS reactive components
- Designing responsive layouts with Tailwind CSS
- Creating Django-Cotton components
- Debugging CSS, JavaScript, or Django issues
- Implementing caching or database optimizations
- Handling geographic data with PostGIS
- Utilizing Redis for session management
- Implementing real-time features with WebSockets
### Context7 Commands
1. **Resolve Library**: Always call `Context7:resolve-library-id` first to get correct library ID
2. **Get Documentation**: Then use `Context7:get-library-docs` with appropriate topic parameter
### Example Topics by Library
- **tailwindcss**: responsive design, flexbox, grid, animations
- **django**: models, views, forms, admin, signals
- **django-cotton**: components, templates, slots, props
- **htmx**: hx-get, hx-post, hx-swap, hx-trigger, hx-target
- **alpinejs**: x-data, x-show, x-if, x-for, x-model
- **django-rest-framework**: serializers, viewsets, routers, permissions
- **postgresql**: joins, indexes, transactions, window functions
- **postgis**: geospatial queries, distance calculations, spatial indexes
- **redis**: caching strategies, pub/sub, data structures
## Code Quality Standards
### Model Requirements
- All models MUST inherit from TrackedModel
- Use SluggedModel for entities with slugs and history tracking
- Always use RichChoiceField instead of Django choices
- Use CloudflareImagesField for all image handling
- Use PostGIS fields and separate location models for geographic data
### API Requirements
- MUST include trailing slashes and follow nested pattern
- All responses MUST use real database queries
- Implement comprehensive filtering and pagination
- Use signal-based cache invalidation
### Development Workflow
- Use uv for all Python package operations
- Use runserver_plus for enhanced development server
- Always use `uv run` for Django management commands
- All functionality MUST work with progressive enhancement

View File

@@ -0,0 +1,56 @@
---
description: Condensed ThrillWiki Django project context with architecture, patterns, and mandatory Context7 integration
author: ThrillWiki Development Team
version: 2.1
globs: ["**/*.py", "**/*.html", "**/*.js", "**/*.css", "**/*.md"]
tags: ["django", "architecture", "context7-integration", "thrillwiki"]
---
# ThrillWiki Django Project Context
## Project Overview
Theme park database platform with Django REST Framework serving 120+ API endpoints for parks, rides, companies, and users.
## Core Architecture
- **Backend**: Django 5.1+, DRF, PostgreSQL+PostGIS, Redis, Celery
- **Frontend**: HTMX (V2+) + AlpineJS + Tailwind CSS (V4+) + Django-Cotton
- 🚨 **ABSOLUTELY NO Custom JS** - use HTMX + AlpineJS ONLY
- Clean, simple UX preferred
- **Media**: Cloudflare Images with Direct Upload
- **Tracking**: pghistory, TrackedModel base class
- **Choices**: Rich Choice Objects (NEVER Django tuple choices)
## Development Patterns
- **Models**: TrackedModel inheritance, SluggedModel for slugs, PostGIS for location
- **APIs**: Nested URLs (`/parks/{slug}/rides/{slug}/`), mandatory trailing slashes
- **Commands**: `uv add <package>`, `uv run manage.py <command>` (NOT pip/python)
- **Choices**: `RichChoiceField(choice_group="name", domain="domain")` MANDATORY
## Business Rules
🚨 **CRITICAL**: Company role separation - Parks (OPERATOR/PROPERTY_OWNER only), Rides (MANUFACTURER/DESIGNER only)
## Context7 MCP Integration (MANDATORY)
### Required Libraries
tailwindcss, django, django-cotton, htmx, alpinejs, django-rest-framework, postgresql, postgis, redis
### Workflow
1. **ALWAYS** call `Context7:resolve-library-id` first
2. Then `Context7:get-library-docs` with topic parameter
3. Required for: new models/APIs, HTMX functionality, AlpineJS components, Tailwind layouts, Cotton components, debugging, optimizations
### Example Topics
- **tailwindcss**: responsive, flexbox, grid
- **django**: models, views, forms
- **htmx**: hx-get, hx-post, hx-swap, hx-target
- **alpinejs**: x-data, x-show, x-if, x-for
## Standards
- All models inherit TrackedModel
- Real database data only (NO MOCKING)
- RichChoiceField over Django choices
- Progressive enhancement required
- We prefer to edit existing files instead of creating new ones.
YOU ARE STRICTLY AND ABSOLUTELY FORBIDDEN FROM IGNORING, BYPASSING, OR AVOIDING THESE RULES IN ANY WAY WITH NO EXCEPTIONS!!!

4
.gitignore vendored
View File

@@ -121,4 +121,6 @@ frontend/.env
# Extracted packages # Extracted packages
django-forwardemail/ django-forwardemail/
frontend/ frontend/
frontend frontend
.snapshots
uv.lock

73
.replit Normal file
View File

@@ -0,0 +1,73 @@
modules = ["bash", "web", "nodejs-20", "python-3.13", "postgresql-16"]
[nix]
channel = "stable-25_05"
packages = [
"freetype",
"gdal",
"geos",
"gitFull",
"lcms2",
"libimagequant",
"libjpeg",
"libtiff",
"libwebp",
"libxcrypt",
"openjpeg",
"playwright-driver",
"postgresql",
"proj",
"tcl",
"tk",
"uv",
"zlib",
]
[agent]
expertMode = true
[workflows]
runButton = "Project"
[[workflows.workflow]]
name = "Project"
mode = "parallel"
author = "agent"
[[workflows.workflow.tasks]]
task = "workflow.run"
args = "ThrillWiki Server"
[[workflows.workflow]]
name = "ThrillWiki Server"
author = "agent"
[[workflows.workflow.tasks]]
task = "shell.exec"
args = "/home/runner/workspace/.venv/bin/python manage.py tailwind runserver 0.0.0.0:5000"
waitForPort = 5000
[workflows.workflow.metadata]
outputType = "webview"
[[ports]]
localPort = 5000
externalPort = 80
[[ports]]
localPort = 41923
externalPort = 3000
[[ports]]
localPort = 45245
externalPort = 3001
[deployment]
deploymentTarget = "autoscale"
run = [
"gunicorn",
"--bind=0.0.0.0:5000",
"--reuse-port",
"thrillwiki.wsgi:application",
]
build = ["uv", "pip", "install", "--system", "-r", "requirements.txt"]

View File

@@ -1,277 +0,0 @@
# ThrillWiki CI/CD System
This repository includes a **complete automated CI/CD system** that creates a Linux VM on Unraid and automatically deploys ThrillWiki when commits are pushed to GitHub.
## 🚀 Complete Automation (Unraid)
For **full automation** including VM creation on Unraid:
```bash
./scripts/unraid/setup-complete-automation.sh
```
This single command will:
- ✅ Create and configure VM on Unraid
- ✅ Install Ubuntu Server with all dependencies
- ✅ Deploy ThrillWiki application
- ✅ Set up automated CI/CD pipeline
- ✅ Configure webhook listener
- ✅ Test the entire system
## Manual Setup (Any Linux VM)
For manual setup on existing Linux VMs:
```bash
./scripts/setup-vm-ci.sh
```
## System Components
### 📁 Files Created
```
scripts/
├── ci-start.sh # Local development server startup
├── webhook-listener.py # GitHub webhook listener
├── vm-deploy.sh # VM deployment script
├── setup-vm-ci.sh # Manual VM setup script
├── unraid/
│ ├── vm-manager.py # Unraid VM management
│ └── setup-complete-automation.sh # Complete automation
└── systemd/
├── thrillwiki.service # Django app service
└── thrillwiki-webhook.service # Webhook listener service
docs/
├── VM_DEPLOYMENT_SETUP.md # Manual setup documentation
└── UNRAID_COMPLETE_AUTOMATION.md # Complete automation guide
```
### 🔄 Deployment Flow
**Complete Automation:**
```
GitHub Push → Webhook → Local Listener → SSH → Unraid VM → Deploy & Restart
```
**Manual Setup:**
```
GitHub Push → Webhook → Local Listener → SSH to VM → Deploy Script → Server Restart
```
## Features
- **Complete VM Automation**: Automatically creates VMs on Unraid
- **Automatic Deployment**: Deploys on push to main branch
- **Health Checks**: Verifies deployment success
- **Rollback Support**: Automatic rollback on deployment failure
- **Service Management**: Systemd integration for reliable service management
- **Database Setup**: Automated PostgreSQL configuration
- **Logging**: Comprehensive logging for debugging
- **Security**: SSH key authentication and webhook secrets
- **One-Command Setup**: Full automation with single script
## Usage
### Complete Automation (Recommended)
For Unraid users, run the complete automation:
```bash
./scripts/unraid/setup-complete-automation.sh
```
After setup, start the webhook listener:
```bash
./start-webhook.sh
```
### Local Development
Start the local development server:
```bash
./scripts/ci-start.sh
```
### VM Management (Unraid)
```bash
# Check VM status
python3 scripts/unraid/vm-manager.py status
# Start/stop VM
python3 scripts/unraid/vm-manager.py start
python3 scripts/unraid/vm-manager.py stop
# Get VM IP
python3 scripts/unraid/vm-manager.py ip
```
### Service Management
On the VM:
```bash
# Check status
ssh thrillwiki-vm "./scripts/vm-deploy.sh status"
# Restart service
ssh thrillwiki-vm "./scripts/vm-deploy.sh restart"
# View logs
ssh thrillwiki-vm "journalctl -u thrillwiki -f"
```
### Manual VM Deployment
Deploy to VM manually:
```bash
ssh thrillwiki-vm "cd thrillwiki && ./scripts/vm-deploy.sh"
```
## Configuration
### Automated Configuration
The complete automation script creates all necessary configuration files:
- `***REMOVED***.unraid` - Unraid VM configuration
- `***REMOVED***.webhook` - Webhook listener configuration
- SSH keys and configuration
- Service configurations
### Manual Environment Variables
For manual setup, create `***REMOVED***.webhook` file:
```bash
WEBHOOK_PORT=9000
WEBHOOK_SECRET=your_secret_here
VM_HOST=your_vm_ip
VM_USER=ubuntu
VM_KEY_PATH=/path/to/ssh/key
VM_PROJECT_PATH=/home/ubuntu/thrillwiki
REPO_URL=https://github.com/username/repo.git
DEPLOY_BRANCH=main
```
### GitHub Webhook
Configure in your GitHub repository:
- **URL**: `http://YOUR_PUBLIC_IP:9000/webhook`
- **Content Type**: `application/json`
- **Secret**: Your webhook secret
- **Events**: Push events
## Requirements
### For Complete Automation
- **Local Machine**: Python 3.8+, SSH client
- **Unraid Server**: 6.8+ with VM support
- **Resources**: 4GB RAM, 50GB disk minimum
- **Ubuntu ISO**: Ubuntu Server 22.04 in `/mnt/user/isos/`
### For Manual Setup
- **Local Machine**: Python 3.8+, SSH access to VM, Public IP
- **Linux VM**: Ubuntu 20.04+, Python 3.8+, UV package manager, Git, SSH server
## Troubleshooting
### Complete Automation Issues
1. **VM Creation Fails**
```bash
# Check Unraid VM support
ssh unraid "virsh list --all"
# Verify Ubuntu ISO exists
ssh unraid "ls -la /mnt/user/isos/ubuntu-*.iso"
```
2. **VM Won't Start**
```bash
# Check VM status
python3 scripts/unraid/vm-manager.py status
# Check Unraid logs
ssh unraid "tail -f /var/log/libvirt/qemu/thrillwiki-vm.log"
```
### General Issues
1. **SSH Connection Failed**
```bash
# Check SSH key permissions
chmod 600 ~/.ssh/thrillwiki_vm
# Test connection
ssh thrillwiki-vm
```
2. **Webhook Not Receiving Events**
```bash
# Check if port is open
sudo ufw allow 9000
# Verify webhook URL in GitHub
curl -X GET http://localhost:9000/health
```
3. **Service Won't Start**
```bash
# Check service logs
ssh thrillwiki-vm "journalctl -u thrillwiki --no-pager"
# Manual start
ssh thrillwiki-vm "cd thrillwiki && ./scripts/ci-start.sh"
```
### Logs
- **Setup logs**: `logs/unraid-automation.log`
- **Local webhook**: `logs/webhook.log`
- **VM deployment**: `logs/deploy.log` (on VM)
- **Django server**: `logs/django.log` (on VM)
- **System logs**: `journalctl -u thrillwiki -f` (on VM)
## Security Notes
- Automated SSH key generation and management
- Dedicated keys for each connection (VM access, Unraid access)
- No password authentication
- Systemd security features enabled
- Firewall configuration support
- Secret management in environment files
## Documentation
- **Complete Automation**: [`docs/UNRAID_COMPLETE_AUTOMATION.md`](docs/UNRAID_COMPLETE_AUTOMATION.md)
- **Manual Setup**: [`docs/VM_DEPLOYMENT_SETUP.md`](docs/VM_DEPLOYMENT_SETUP.md)
---
## Quick Start Summary
### For Unraid Users (Complete Automation)
```bash
# One command to set up everything
./scripts/unraid/setup-complete-automation.sh
# Start webhook listener
./start-webhook.sh
# Push commits to auto-deploy!
```
### For Existing VM Users
```bash
# Manual setup
./scripts/setup-vm-ci.sh
# Configure webhook and push to deploy
```
**The system will automatically deploy your Django application whenever you push commits to the main branch!** 🚀

View File

@@ -1,232 +0,0 @@
# Critical Analysis: Current HTMX + Alpine.js Implementation
## Executive Summary
After thorough analysis, the current HTMX + Alpine.js implementation has **significant gaps** compared to the React frontend functionality. While the foundation exists, there are critical missing pieces that prevent it from being a true replacement for the React frontend.
## Major Issues Identified
### 1. **Incomplete Component Parity** ❌
**React Frontend Has:**
- Sophisticated park/ride cards with hover effects, ratings, status badges
- Advanced search with autocomplete and real-time suggestions
- Complex filtering UI with multiple filter types
- Rich user profile management
- Modal-based authentication flows
- Theme switching with system preference detection
- Responsive image handling with Next.js Image optimization
**Current Django Templates Have:**
- Basic card layouts without advanced interactions
- Simple search without autocomplete
- Limited filtering capabilities
- Basic user menus
- No modal authentication system
- Basic theme toggle
### 2. **Missing Critical Pages** ❌
**React Frontend Pages Not Implemented:**
- `/profile` - User profile management
- `/settings` - User settings and preferences
- `/api-test` - API testing interface
- `/test-ride` - Ride testing components
- Advanced search results page
- User dashboard/account management
**Current Django Only Has:**
- Basic park/ride listing pages
- Simple detail pages
- Admin/moderation interfaces
### 3. **Inadequate State Management** ❌
**React Frontend Uses:**
- Complex state management with custom hooks
- Global authentication state
- Theme provider with system detection
- Search state with debouncing
- Filter state with URL synchronization
**Current Alpine.js Has:**
- Basic component-level state
- Simple theme toggle
- No global state management
- No URL state synchronization
- No proper error handling
### 4. **Poor API Integration** ❌
**React Frontend Features:**
- TypeScript API clients with proper typing
- Error handling and loading states
- Optimistic updates
- Proper authentication headers
- Response caching
**Current HTMX Implementation:**
- Basic HTMX requests without error handling
- No loading states
- No proper authentication integration
- No response validation
- No caching strategy
### 5. **Missing Advanced UI Components** ❌
**React Frontend Components Missing:**
- Advanced data tables with sorting/filtering
- Image galleries with lightbox
- Multi-step forms
- Rich text editors
- Date/time pickers
- Advanced modals and dialogs
- Toast notifications system
- Skeleton loading states
### 6. **Inadequate Mobile Experience** ❌
**React Frontend Mobile Features:**
- Responsive design with proper breakpoints
- Touch-optimized interactions
- Mobile-specific navigation patterns
- Swipe gestures
- Mobile-optimized forms
**Current Implementation:**
- Basic responsive layout
- No touch optimizations
- Simple mobile menu
- No mobile-specific interactions
## Specific Technical Gaps
### Authentication System
```html
<!-- Current: Basic login links -->
<a href="{% url 'account_login' %}">Login</a>
<!-- Needed: Modal-based auth like React -->
<div x-data="authModal()" x-show="open" class="modal">
<!-- Complex auth flow with validation -->
</div>
```
### Search Functionality
```javascript
// Current: Basic search
Alpine.data('searchComponent', () => ({
query: '',
async search() {
// Basic fetch without proper error handling
}
}))
// Needed: Advanced search like React
Alpine.data('advancedSearch', () => ({
query: '',
filters: {},
suggestions: [],
loading: false,
debounceTimer: null,
// Complex search logic with debouncing, caching, etc.
}))
```
### Component Architecture
```html
<!-- Current: Basic templates -->
<div class="card">
<h3>{{ park.name }}</h3>
</div>
<!-- Needed: Rich components like React -->
<div x-data="parkCard({{ park|json }})" class="park-card">
<!-- Complex interactions, animations, state management -->
</div>
```
## Performance Issues
### 1. **No Code Splitting**
- React frontend uses dynamic imports and code splitting
- Current implementation loads everything upfront
- No lazy loading of components or routes
### 2. **Inefficient HTMX Usage**
- Multiple HTMX requests for simple interactions
- No request batching or optimization
- No proper caching headers
### 3. **Poor Asset Management**
- No asset optimization
- No image optimization (missing Next.js Image equivalent)
- No CSS/JS minification strategy
## Missing Developer Experience
### 1. **No Type Safety**
- React frontend has full TypeScript support
- Current implementation has no type checking
- No API contract validation
### 2. **Poor Error Handling**
- No global error boundaries
- No proper error reporting
- No user-friendly error messages
### 3. **No Testing Strategy**
- React frontend has component testing
- Current implementation has no frontend tests
- No integration testing
## Critical Missing Features
### 1. **Real-time Features**
- No WebSocket integration
- No live updates
- No real-time notifications
### 2. **Advanced Interactions**
- No drag and drop
- No complex animations
- No keyboard navigation
- No accessibility features
### 3. **Data Management**
- No client-side caching
- No optimistic updates
- No offline support
- No data synchronization
## Recommended Action Plan
### Phase 1: Critical Component Migration (High Priority)
1. **Authentication System** - Implement modal-based auth with proper validation
2. **Advanced Search** - Build autocomplete with debouncing and caching
3. **User Profile/Settings** - Create comprehensive user management
4. **Enhanced Cards** - Implement rich park/ride cards with interactions
### Phase 2: Advanced Features (Medium Priority)
1. **State Management** - Implement proper global state with Alpine stores
2. **API Integration** - Build robust API client with error handling
3. **Mobile Optimization** - Enhance mobile experience
4. **Performance** - Implement caching and optimization
### Phase 3: Polish and Testing (Low Priority)
1. **Error Handling** - Implement comprehensive error boundaries
2. **Testing** - Add frontend testing suite
3. **Accessibility** - Ensure WCAG compliance
4. **Documentation** - Create comprehensive component docs
## Conclusion
The current HTMX + Alpine.js implementation is **NOT ready** to replace the React frontend. It's missing approximately **60-70%** of the functionality and sophistication of the React application.
A proper migration requires:
- **3-4 weeks of intensive development**
- **Complete rewrite of most components**
- **New architecture for state management**
- **Comprehensive testing and optimization**
The existing Django templates are a good foundation, but they need **significant enhancement** to match the React frontend's capabilities.

View File

@@ -1,258 +0,0 @@
# Frontend Migration Plan: React/Next.js to HTMX + Alpine.js
## Executive Summary
Based on my analysis, this project already has a **fully functional HTMX + Alpine.js Django backend** with comprehensive templates. The task is to migrate the separate Next.js React frontend (`frontend/` directory) to integrate seamlessly with the existing Django HTMX + Alpine.js architecture.
## Current State Analysis
### ✅ Django Backend (Already Complete)
- **HTMX Integration**: Already implemented with proper headers and partial templates
- **Alpine.js Components**: Extensive use of Alpine.js for interactivity
- **Template Structure**: Comprehensive template hierarchy with partials
- **Authentication**: Complete auth system with modals and forms
- **Styling**: Tailwind CSS with dark mode support
- **Components**: Reusable components for cards, pagination, forms, etc.
### 🔄 React Frontend (To Be Migrated)
- **Next.js App Router**: Modern React application structure
- **Component Library**: Extensive UI components using shadcn/ui
- **Authentication**: React-based auth hooks and providers
- **Theme Management**: React theme provider system
- **API Integration**: TypeScript API clients for Django backend
## Migration Strategy
### Phase 1: Template Enhancement (Extend Django Templates)
Instead of replacing the existing Django templates, we'll enhance them to match the React frontend's design and functionality.
#### 1.1 Header Component Migration
**Current Django**: Basic header with navigation
**React Frontend**: Advanced header with browse menu, search, theme toggle, user dropdown
**Action**: Enhance `backend/templates/base/base.html` header section
#### 1.2 Component Library Integration
**Current Django**: Basic components
**React Frontend**: Rich component library (buttons, cards, modals, etc.)
**Action**: Create Django template components matching shadcn/ui design system
#### 1.3 Advanced Interactivity
**Current Django**: Basic Alpine.js usage
**React Frontend**: Complex state management and interactions
**Action**: Enhance Alpine.js components with advanced patterns
### Phase 2: Django View Enhancements
#### 2.1 API Response Optimization
- Enhance existing Django views to support both full page and HTMX partial responses
- Implement proper JSON responses for Alpine.js components
- Add advanced filtering and search capabilities
#### 2.2 Authentication Flow
- Enhance existing Django auth to match React frontend UX
- Implement modal-based login/signup (already partially done)
- Add proper error handling and validation
### Phase 3: Frontend Asset Migration
#### 3.1 Static Assets
- Migrate React component styles to Django static files
- Enhance Tailwind configuration
- Add missing JavaScript utilities
#### 3.2 Alpine.js Store Management
- Implement global state management using Alpine.store()
- Create reusable Alpine.js components using Alpine.data()
- Add proper event handling and communication
## Implementation Plan
### Step 1: Analyze Component Gaps
Compare React components with Django templates to identify missing functionality:
1. **Browse Menu**: React has sophisticated browse dropdown
2. **Search Functionality**: React has advanced search with autocomplete
3. **Theme Toggle**: React has system/light/dark theme support
4. **User Management**: React has comprehensive user profile management
5. **Modal System**: React has advanced modal components
6. **Form Handling**: React has sophisticated form validation
### Step 2: Enhance Django Templates
#### Base Template Enhancements
```html
<!-- Enhanced header with browse menu -->
<div class="browse-menu" x-data="browseMenu()">
<!-- Implement React-style browse menu -->
</div>
<!-- Enhanced search with autocomplete -->
<div class="search-container" x-data="searchComponent()">
<!-- Implement React-style search -->
</div>
```
#### Alpine.js Component Library
```javascript
// Global Alpine.js components
Alpine.data('browseMenu', () => ({
open: false,
toggle() { this.open = !this.open }
}))
Alpine.data('searchComponent', () => ({
query: '',
results: [],
async search() {
// Implement search logic
}
}))
```
### Step 3: Django View Enhancements
#### Enhanced Views for HTMX
```python
def enhanced_park_list(request):
if request.headers.get('HX-Request'):
# Return partial template for HTMX
return render(request, 'parks/partials/park_list.html', context)
# Return full page
return render(request, 'parks/park_list.html', context)
```
### Step 4: Component Migration Priority
1. **Header Component** (High Priority)
- Browse menu with categories
- Advanced search with autocomplete
- User dropdown with profile management
- Theme toggle with system preference
2. **Navigation Components** (High Priority)
- Mobile menu with slide-out
- Breadcrumb navigation
- Tab navigation
3. **Form Components** (Medium Priority)
- Advanced form validation
- File upload components
- Multi-step forms
4. **Data Display Components** (Medium Priority)
- Advanced card layouts
- Data tables with sorting/filtering
- Pagination components
5. **Modal and Dialog Components** (Low Priority)
- Confirmation dialogs
- Image galleries
- Settings panels
## Technical Implementation Details
### HTMX Patterns to Implement
1. **Lazy Loading**
```html
<div hx-get="/api/parks/" hx-trigger="intersect" hx-swap="innerHTML">
Loading parks...
</div>
```
2. **Infinite Scroll**
```html
<div hx-get="/api/parks/?page=2" hx-trigger="revealed" hx-swap="beforeend">
Load more...
</div>
```
3. **Live Search**
```html
<input hx-get="/api/search/" hx-trigger="input changed delay:300ms"
hx-target="#search-results">
```
### Alpine.js Patterns to Implement
1. **Global State Management**
```javascript
Alpine.store('app', {
user: null,
theme: 'system',
searchQuery: ''
})
```
2. **Reusable Components**
```javascript
Alpine.data('modal', () => ({
open: false,
show() { this.open = true },
hide() { this.open = false }
}))
```
## File Structure After Migration
```
backend/
├── templates/
│ ├── base/
│ │ ├── base.html (enhanced)
│ │ └── components/
│ │ ├── header.html
│ │ ├── footer.html
│ │ ├── navigation.html
│ │ └── search.html
│ ├── components/
│ │ ├── ui/
│ │ │ ├── button.html
│ │ │ ├── card.html
│ │ │ ├── modal.html
│ │ │ └── form.html
│ │ └── layout/
│ │ ├── browse_menu.html
│ │ └── user_menu.html
│ └── partials/
│ ├── htmx/
│ └── alpine/
├── static/
│ ├── js/
│ │ ├── alpine-components.js
│ │ ├── htmx-config.js
│ │ └── app.js
│ └── css/
│ ├── components.css
│ └── tailwind.css
```
## Success Metrics
1. **Functionality Parity**: All React frontend features work in Django templates
2. **Design Consistency**: Visual design matches React frontend exactly
3. **Performance**: Page load times improved due to server-side rendering
4. **User Experience**: Smooth interactions with HTMX and Alpine.js
5. **Maintainability**: Clean, reusable template components
## Timeline Estimate
- **Phase 1**: Template Enhancement (3-4 days)
- **Phase 2**: Django View Enhancements (2-3 days)
- **Phase 3**: Frontend Asset Migration (2-3 days)
- **Testing & Refinement**: 2-3 days
**Total Estimated Time**: 9-13 days
## Next Steps
1. **Immediate**: Start with header component migration
2. **Priority**: Focus on high-impact components first
3. **Testing**: Implement comprehensive testing for each migrated component
4. **Documentation**: Update all documentation to reflect new architecture
This migration will result in a unified, server-rendered application with the rich interactivity of the React frontend but the performance and simplicity of HTMX + Alpine.js.

View File

@@ -1,207 +0,0 @@
# Frontend Migration Implementation Summary
## What We've Accomplished ✅
### 1. **Critical Analysis Completed**
- Identified that current HTMX + Alpine.js implementation was missing **60-70%** of React frontend functionality
- Documented specific gaps in authentication, search, state management, and UI components
- Created detailed comparison between React and Django implementations
### 2. **Enhanced Authentication System** 🎯
**Problem**: Django only had basic page-based login forms
**Solution**: Created sophisticated modal-based authentication system
**Files Created/Modified:**
- `backend/templates/components/auth/auth-modal.html` - Complete modal auth component
- `backend/static/js/alpine-components.js` - Enhanced with `authModal()` Alpine component
- `backend/templates/base/base.html` - Added global auth modal
- `backend/templates/components/layout/enhanced_header.html` - Updated to use modal auth
**Features Implemented:**
- Modal-based login/register (matches React AuthDialog)
- Social authentication integration (Google, Discord)
- Form validation and error handling
- Password visibility toggle
- Smooth transitions and animations
- Global accessibility via `window.authModal`
### 3. **Advanced Toast Notification System** 🎯
**Problem**: No toast notification system like React's Sonner
**Solution**: Created comprehensive toast system with progress bars
**Files Created:**
- `backend/templates/components/ui/toast-container.html` - Toast UI component
- Enhanced Alpine.js with global toast store and component
**Features Implemented:**
- Multiple toast types (success, error, warning, info)
- Progress bar animations
- Auto-dismiss with configurable duration
- Smooth slide-in/out animations
- Global store for app-wide access
### 4. **Enhanced Alpine.js Architecture** 🎯
**Problem**: Basic Alpine.js components without sophisticated state management
**Solution**: Created comprehensive component library
**Components Added:**
- `authModal()` - Complete authentication flow
- Enhanced `toast()` - Advanced notification system
- Global stores for app state and toast management
- Improved error handling and API integration
### 5. **Improved Header Component** 🎯
**Problem**: Header didn't match React frontend sophistication
**Solution**: Enhanced header with modal integration
**Features Added:**
- Modal authentication buttons (instead of page redirects)
- Proper Alpine.js integration
- Maintained all existing functionality (browse menu, search, theme toggle)
## Current State Assessment
### ✅ **Completed Components**
1. **Authentication System** - Modal-based auth matching React functionality
2. **Toast Notifications** - Advanced toast system with animations
3. **Theme Management** - Already working well
4. **Header Navigation** - Enhanced with modal integration
5. **Base Template Structure** - Solid foundation with global components
### ⚠️ **Partially Complete**
1. **Search Functionality** - Basic HTMX search exists, needs autocomplete enhancement
2. **User Profile/Settings** - Basic pages exist, need React-level sophistication
3. **Card Components** - Basic cards exist, need hover effects and advanced interactions
### ❌ **Still Missing (High Priority)**
1. **Advanced Search with Autocomplete** - React has sophisticated search with suggestions
2. **Enhanced Park/Ride Cards** - Need hover effects, animations, better interactions
3. **User Profile Management** - React has comprehensive profile editing
4. **Settings Page** - React has advanced settings with multiple sections
5. **Mobile Optimization** - Need touch-optimized interactions
6. **Loading States** - Need skeleton loaders and proper loading indicators
### ❌ **Still Missing (Medium Priority)**
1. **Advanced Filtering UI** - React has complex filter interfaces
2. **Image Galleries** - React has lightbox and advanced image handling
3. **Data Tables** - React has sortable, filterable tables
4. **Form Validation** - Need client-side validation matching React
5. **Pagination Components** - Need enhanced pagination with proper state
## Next Steps for Complete Migration
### Phase 1: Critical Missing Components (1-2 weeks)
#### 1. Enhanced Search with Autocomplete
```javascript
// Need to implement in Alpine.js
Alpine.data('advancedSearch', () => ({
query: '',
suggestions: [],
loading: false,
showSuggestions: false,
// Advanced search logic with debouncing, caching
}))
```
#### 2. Enhanced Park/Ride Cards
```html
<!-- Need to create sophisticated card component -->
<div x-data="parkCard({{ park|json }})" class="park-card">
<!-- Hover effects, animations, interactions -->
</div>
```
#### 3. User Profile/Settings Pages
- Create comprehensive profile editing interface
- Add avatar upload with preview
- Implement settings sections (privacy, notifications, etc.)
### Phase 2: Advanced Features (2-3 weeks)
#### 1. Advanced Filtering System
- Multi-select filters
- Range sliders
- Date pickers
- URL state synchronization
#### 2. Enhanced Mobile Experience
- Touch-optimized interactions
- Swipe gestures
- Mobile-specific navigation patterns
#### 3. Loading States and Skeletons
- Skeleton loading components
- Proper loading indicators
- Optimistic updates
### Phase 3: Polish and Optimization (1 week)
#### 1. Performance Optimization
- Lazy loading
- Image optimization
- Request batching
#### 2. Accessibility Improvements
- ARIA labels
- Keyboard navigation
- Screen reader support
#### 3. Testing and Documentation
- Component testing
- Integration testing
- Comprehensive documentation
## Technical Architecture
### Current Stack
- **Backend**: Django with HTMX middleware
- **Frontend**: HTMX + Alpine.js + Tailwind CSS
- **Components**: shadcn/ui-inspired design system
- **State Management**: Alpine.js stores + component-level state
- **Authentication**: Modal-based with social auth integration
### Key Patterns Established
1. **Global Component Access**: `window.authModal` pattern for cross-component communication
2. **Store-based State**: Alpine.store() for global state management
3. **HTMX + Alpine Integration**: Seamless server-client interaction
4. **Component Templates**: Reusable Django template components
5. **Progressive Enhancement**: Works without JavaScript, enhanced with it
## Success Metrics
### ✅ **Achieved**
- Modal authentication system (100% React parity)
- Toast notification system (100% React parity)
- Theme management (100% React parity)
- Base template architecture (solid foundation)
### 🎯 **In Progress**
- Search functionality (60% complete)
- Card components (40% complete)
- User management (30% complete)
### ❌ **Not Started**
- Advanced filtering (0% complete)
- Mobile optimization (0% complete)
- Loading states (0% complete)
## Estimated Completion Time
**Total Remaining Work**: 4-6 weeks
- **Phase 1 (Critical)**: 1-2 weeks
- **Phase 2 (Advanced)**: 2-3 weeks
- **Phase 3 (Polish)**: 1 week
## Conclusion
We've successfully implemented the **most critical missing piece** - the authentication system - which was a major gap between the React and Django implementations. The foundation is now solid with:
1. **Sophisticated modal authentication** matching React functionality
2. **Advanced toast notification system** with animations and global state
3. **Enhanced Alpine.js architecture** with proper component patterns
4. **Solid template structure** for future component development
The remaining work is primarily about **enhancing existing components** rather than building fundamental architecture. The hardest part (authentication and global state management) is complete.
**Recommendation**: Continue with Phase 1 implementation focusing on search enhancement and card component improvements, as these will provide the most visible user experience improvements.

443
README.md
View File

@@ -1,200 +1,87 @@
# ThrillWiki Django + Vue.js Monorepo # ThrillWiki Backend
A comprehensive theme park and roller coaster information system built with a modern monorepo architecture combining Django REST API backend with Vue.js frontend. Django REST API backend for the ThrillWiki monorepo.
## 🏗️ Architecture Overview ## 🏗️ Architecture
This project uses a monorepo structure that cleanly separates backend and frontend concerns while maintaining shared resources and documentation: This backend follows Django best practices with a modular app structure:
``` ```
thrillwiki-monorepo/ backend/
├── backend/ # Django REST API (Port 8000) ├── apps/ # Django applications
│ ├── apps/ # Modular Django applications │ ├── accounts/ # User management
│ ├── config/ # Django settings and configuration │ ├── parks/ # Theme park data
│ ├── templates/ # Django templates │ ├── rides/ # Ride information
── static/ # Static assets ── moderation/ # Content moderation
├── frontend/ # Vue.js SPA (Port 5174) │ ├── location/ # Geographic data
│ ├── src/ # Vue.js source code │ ├── media/ # File management
│ ├── public/ # Static assets │ ├── email_service/ # Email functionality
│ └── dist/ # Build output │ └── core/ # Core utilities
├── shared/ # Shared resources and documentation ├── config/ # Django configuration
│ ├── docs/ # Comprehensive documentation │ ├── django/ # Settings files
── scripts/ # Development and deployment scripts ── settings/ # Modular settings
│ ├── config/ # Shared configuration ├── templates/ # Django templates
│ └── media/ # Shared media files ├── static/ # Static files
── architecture/ # Architecture documentation ── tests/ # Test files
└── profiles/ # Development profiles
``` ```
## 🛠️ Technology Stack
- **Django 5.0+** - Web framework
- **Django REST Framework** - API framework
- **PostgreSQL** - Primary database
- **Redis** - Caching and sessions
- **UV** - Python package management
- **Celery** - Background task processing
## 🚀 Quick Start ## 🚀 Quick Start
### Prerequisites ### Prerequisites
- **Python 3.11+** with [uv](https://docs.astral.sh/uv/) for backend dependencies - Python 3.11+
- **Node.js 18+** with [pnpm](https://pnpm.io/) for frontend dependencies - [uv](https://docs.astral.sh/uv/) package manager
- **PostgreSQL 14+** (optional, defaults to SQLite for development) - PostgreSQL 14+
- **Redis 6+** (optional, for caching and sessions) - Redis 6+
### Development Setup ### Setup
1. **Clone the repository** 1. **Install dependencies**
```bash
git clone <repository-url>
cd thrillwiki-monorepo
```
2. **Install dependencies**
```bash
# Install frontend dependencies
pnpm install
# Install backend dependencies
cd backend && uv sync && cd ..
```
3. **Environment configuration**
```bash
# Copy environment files
cp .env.example .env
cp backend/.env.example backend/.env
cp frontend/.env.development frontend/.env.local
# Edit .env files with your settings
```
4. **Database setup**
```bash ```bash
cd backend cd backend
uv sync
```
2. **Environment configuration**
```bash
cp .env.example .env
# Edit .env with your settings
```
3. **Database setup**
```bash
uv run manage.py migrate uv run manage.py migrate
uv run manage.py createsuperuser uv run manage.py createsuperuser
cd ..
``` ```
5. **Start development servers** 4. **Start development server**
```bash ```bash
# Start both servers concurrently uv run manage.py runserver
pnpm run dev
# Or start individually
pnpm run dev:frontend # Vue.js on :5174
pnpm run dev:backend # Django on :8000
``` ```
## 📁 Project Structure Details
### Backend (`/backend`)
- **Django 5.0+** with REST Framework for API development
- **Modular app architecture** with separate apps for parks, rides, accounts, etc.
- **UV package management** for fast, reliable Python dependency management
- **PostgreSQL/SQLite** database with comprehensive entity relationships
- **Redis** for caching, sessions, and background tasks
- **Comprehensive API** with frontend serializers for camelCase conversion
### Frontend (`/frontend`)
- **Vue 3** with Composition API and `<script setup>` syntax
- **TypeScript** for type safety and better developer experience
- **Vite** for lightning-fast development and optimized production builds
- **Tailwind CSS** with custom design system and dark mode support
- **Pinia** for state management with modular stores
- **Vue Router** for client-side routing
- **Comprehensive UI component library** with shadcn-vue components
### Shared Resources (`/shared`)
- **Documentation** - Comprehensive guides and API documentation
- **Development scripts** - Automated setup, build, and deployment scripts
- **Configuration** - Shared Docker, CI/CD, and infrastructure configs
- **Media management** - Centralized media file handling and optimization
## 🛠️ Development Workflow
### Available Scripts
```bash
# Development
pnpm run dev # Start both servers concurrently
pnpm run dev:frontend # Frontend only (:5174)
pnpm run dev:backend # Backend only (:8000)
# Building
pnpm run build # Build frontend for production
pnpm run build:staging # Build for staging environment
pnpm run build:production # Build for production environment
# Testing
pnpm run test # Run all tests
pnpm run test:frontend # Frontend unit and E2E tests
pnpm run test:backend # Backend unit and integration tests
# Code Quality
pnpm run lint # Lint all code
pnpm run type-check # TypeScript type checking
# Setup and Maintenance
pnpm run install:all # Install all dependencies
./shared/scripts/dev/setup-dev.sh # Full development setup
./shared/scripts/dev/start-all.sh # Start all services
```
### Backend Development
```bash
cd backend
# Django management commands
uv run manage.py migrate
uv run manage.py makemigrations
uv run manage.py createsuperuser
uv run manage.py collectstatic
# Testing and quality
uv run manage.py test
uv run black . # Format code
uv run flake8 . # Lint code
uv run isort . # Sort imports
```
### Frontend Development
```bash
cd frontend
# Vue.js development
pnpm run dev # Start dev server
pnpm run build # Production build
pnpm run preview # Preview production build
pnpm run test:unit # Vitest unit tests
pnpm run test:e2e # Playwright E2E tests
pnpm run lint # ESLint
pnpm run type-check # TypeScript checking
```
## 🔧 Configuration ## 🔧 Configuration
### Environment Variables ### Environment Variables
#### Root `.env` Required environment variables:
```bash ```bash
# Database # Database
DATABASE_URL=postgresql://user:pass@localhost/thrillwiki DATABASE_URL=postgresql://user:pass@localhost/thrillwiki
REDIS_URL=redis://localhost:6379
# Security # Django
SECRET_KEY=your-secret-key SECRET_KEY=your-secret-key
DEBUG=True DEBUG=True
# API Configuration
API_BASE_URL=http://localhost:8000/api
```
#### Backend `.env`
```bash
# Django Settings
DJANGO_SETTINGS_MODULE=config.django.local DJANGO_SETTINGS_MODULE=config.django.local
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1
# Database
DATABASE_URL=postgresql://user:pass@localhost/thrillwiki
# Redis # Redis
REDIS_URL=redis://localhost:6379 REDIS_URL=redis://localhost:6379
@@ -203,142 +90,140 @@ REDIS_URL=redis://localhost:6379
EMAIL_HOST=smtp.gmail.com EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587 EMAIL_PORT=587
EMAIL_USE_TLS=True EMAIL_USE_TLS=True
EMAIL_HOST_USER=your-email@gmail.com
EMAIL_HOST_PASSWORD=your-app-password
``` ```
#### Frontend `.env.local` ### Settings Structure
- `config/django/base.py` - Base settings
- `config/django/local.py` - Development settings
- `config/django/production.py` - Production settings
- `config/django/test.py` - Test settings
## 📁 Apps Overview
### Core Apps
- **accounts** - User authentication and profile management
- **parks** - Theme park models and operations
- **rides** - Ride information and relationships
- **core** - Shared utilities and base classes
### Support Apps
- **moderation** - Content moderation workflows
- **location** - Geographic data and services
- **media** - File upload and management
- **email_service** - Email sending and templates
## 🔌 API Endpoints
Base URL: `http://localhost:8000/api/`
### Authentication
- `POST /auth/login/` - User login
- `POST /auth/logout/` - User logout
- `POST /auth/register/` - User registration
### Parks
- `GET /parks/` - List parks
- `GET /parks/{id}/` - Park details
- `POST /parks/` - Create park (admin)
### Rides
- `GET /rides/` - List rides
- `GET /rides/{id}/` - Ride details
- `GET /parks/{park_id}/rides/` - Rides by park
## 🧪 Testing
```bash ```bash
# API Configuration # Run all tests
VITE_API_BASE_URL=http://localhost:8000/api uv run manage.py test
# Development # Run specific app tests
VITE_APP_TITLE=ThrillWiki (Development) uv run manage.py test apps.parks
# Feature Flags # Run with coverage
VITE_ENABLE_DEBUG=true uv run coverage run manage.py test
uv run coverage report
``` ```
## 📊 Key Features ## 🔧 Management Commands
### Backend Features Custom management commands:
- **Comprehensive Park Database** - Detailed information about theme parks worldwide
- **Extensive Ride Database** - Complete roller coaster and ride information
- **User Management** - Authentication, profiles, and permissions
- **Content Moderation** - Review and approval workflows
- **API Documentation** - Auto-generated OpenAPI/Swagger docs
- **Background Tasks** - Celery integration for long-running processes
- **Caching Strategy** - Redis-based caching for performance
- **Search Functionality** - Full-text search across all content
### Frontend Features ```bash
- **Responsive Design** - Mobile-first approach with Tailwind CSS # Import park data
- **Dark Mode Support** - Complete dark/light theme system uv run manage.py import_parks data/parks.json
- **Real-time Search** - Instant search with debouncing and highlighting
- **Interactive Maps** - Park and ride location visualization
- **Photo Galleries** - High-quality image management
- **User Dashboard** - Personalized content and contributions
- **Progressive Web App** - PWA capabilities for mobile experience
- **Accessibility** - WCAG 2.1 AA compliance
## 📖 Documentation # Generate test data
uv run manage.py generate_test_data
### Core Documentation # Clean up expired sessions
- **[Backend Documentation](./backend/README.md)** - Django setup and API details uv run manage.py clearsessions
- **[Frontend Documentation](./frontend/README.md)** - Vue.js setup and development ```
- **[API Documentation](./shared/docs/api/README.md)** - Complete API reference
- **[Development Workflow](./shared/docs/development/workflow.md)** - Daily development processes
### Architecture & Deployment ## 📊 Database
- **[Architecture Overview](./architecture/)** - System design and decisions
- **[Deployment Guide](./shared/docs/deployment/)** - Production deployment instructions
- **[Development Scripts](./shared/scripts/)** - Automation and tooling
### Additional Resources ### Entity Relationships
- **[Contributing Guide](./CONTRIBUTING.md)** - How to contribute to the project
- **[Code of Conduct](./CODE_OF_CONDUCT.md)** - Community guidelines - **Parks** have Operators (required) and PropertyOwners (optional)
- **[Security Policy](./SECURITY.md)** - Security reporting and policies - **Rides** belong to Parks and may have Manufacturers/Designers
- **Users** can create submissions and moderate content
### Migrations
```bash
# Create migrations
uv run manage.py makemigrations
# Apply migrations
uv run manage.py migrate
# Show migration status
uv run manage.py showmigrations
```
## 🔐 Security
- CORS configured for frontend integration
- CSRF protection enabled
- JWT token authentication
- Rate limiting on API endpoints
- Input validation and sanitization
## 📈 Performance
- Database query optimization
- Redis caching for frequent queries
- Background task processing with Celery
- Database connection pooling
## 🚀 Deployment ## 🚀 Deployment
### Development Environment See the [Deployment Guide](../shared/docs/deployment/) for production setup.
```bash
# Quick start with all services
./shared/scripts/dev/start-all.sh
# Full development setup ## 🐛 Debugging
./shared/scripts/dev/setup-dev.sh
```
### Production Deployment ### Development Tools
```bash
# Build all components
./shared/scripts/build/build-all.sh
# Deploy to production - Django Debug Toolbar
./shared/scripts/deploy/deploy.sh - Django Extensions
``` - Silk profiler for performance analysis
See [Deployment Guide](./shared/docs/deployment/) for detailed production setup instructions. ### Logging
## 🧪 Testing Strategy Logs are written to:
- Console (development)
### Backend Testing - Files in `logs/` directory (production)
- **Unit Tests** - Individual function and method testing - External logging service (production)
- **Integration Tests** - API endpoint and database interaction testing
- **E2E Tests** - Full user journey testing with Selenium
### Frontend Testing
- **Unit Tests** - Component and utility function testing with Vitest
- **Integration Tests** - Component interaction testing
- **E2E Tests** - User journey testing with Playwright
### Code Quality
- **Linting** - ESLint for JavaScript/TypeScript, Flake8 for Python
- **Type Checking** - TypeScript for frontend, mypy for Python
- **Code Formatting** - Prettier for frontend, Black for Python
## 🤝 Contributing ## 🤝 Contributing
We welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details on: 1. Follow Django coding standards
2. Write tests for new features
1. **Development Setup** - Getting your development environment ready 3. Update documentation
2. **Code Standards** - Coding conventions and best practices 4. Run linting: `uv run flake8 .`
3. **Pull Request Process** - How to submit your changes 5. Format code: `uv run black .`
4. **Issue Reporting** - How to report bugs and request features
### Quick Contribution Start
```bash
# Fork and clone the repository
git clone https://github.com/your-username/thrillwiki-monorepo.git
cd thrillwiki-monorepo
# Set up development environment
./shared/scripts/dev/setup-dev.sh
# Create a feature branch
git checkout -b feature/your-feature-name
# Make your changes and test
pnpm run test
# Submit a pull request
```
## 📄 License
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
## 🙏 Acknowledgments
- **Theme Park Community** - For providing data and inspiration
- **Open Source Contributors** - For the amazing tools and libraries
- **Vue.js and Django Communities** - For excellent documentation and support
## 📞 Support
- **Issues** - [GitHub Issues](https://github.com/your-repo/thrillwiki-monorepo/issues)
- **Discussions** - [GitHub Discussions](https://github.com/your-repo/thrillwiki-monorepo/discussions)
- **Documentation** - [Project Wiki](https://github.com/your-repo/thrillwiki-monorepo/wiki)
---
**Built with ❤️ for the theme park and roller coaster community**

View File

@@ -1,180 +0,0 @@
# ThrillWiki Hybrid Filtering Endpoints Test Suite
This repository contains a comprehensive test script for the newly synchronized Parks and Rides hybrid filtering endpoints.
## Quick Start
1. **Start the Django server:**
```bash
cd backend && uv run manage.py runserver 8000
```
2. **Run the test script:**
```bash
./test_hybrid_endpoints.sh
```
Or with a custom base URL:
```bash
./test_hybrid_endpoints.sh http://localhost:8000
```
## What Gets Tested
### Parks Hybrid Filtering (`/api/v1/parks/hybrid/`)
- ✅ Basic hybrid filtering (automatic strategy selection)
- ✅ Search functionality (`?search=disney`)
- ✅ Status filtering (`?status=OPERATING,CLOSED_TEMP`)
- ✅ Geographic filtering (`?country=United%20States&state=Florida,California`)
- ✅ Numeric range filtering (`?opening_year_min=1990&rating_min=4.0`)
- ✅ Park statistics filtering (`?size_min=100&ride_count_min=10`)
- ✅ Operator filtering (`?operator=disney,universal`)
- ✅ Progressive loading (`?offset=50`)
- ✅ Filter metadata (`/filter-metadata/`)
- ✅ Scoped metadata (`/filter-metadata/?scoped=true&country=United%20States`)
### Rides Hybrid Filtering (`/api/v1/rides/hybrid/`)
- ✅ Basic hybrid filtering (automatic strategy selection)
- ✅ Search functionality (`?search=coaster`)
- ✅ Category filtering (`?category=RC,DR`)
- ✅ Status and park filtering (`?status=OPERATING&park_slug=cedar-point`)
- ✅ Manufacturer/designer filtering (`?manufacturer=bolliger-mabillard`)
- ✅ Roller coaster specific filtering (`?roller_coaster_type=INVERTED&has_inversions=true`)
- ✅ Performance filtering (`?height_ft_min=200&speed_mph_min=70`)
- ✅ Quality metrics (`?rating_min=4.5&capacity_min=1000`)
- ✅ Accessibility filtering (`?height_requirement_min=48&height_requirement_max=54`)
- ✅ Progressive loading (`?offset=25&category=RC`)
- ✅ Filter metadata (`/filter-metadata/`)
- ✅ Scoped metadata (`/filter-metadata/?scoped=true&category=RC`)
### Advanced Testing
- ✅ Complex combination queries
- ✅ Edge cases (empty results, invalid parameters)
- ✅ Performance timing comparisons
- ✅ Error handling validation
## Key Features Demonstrated
### 🔄 Automatic Strategy Selection
- **≤200 records**: Client-side filtering (loads all data for frontend filtering)
- **>200 records**: Server-side filtering (database filtering with pagination)
### 📊 Progressive Loading
- Initial load: 50 records
- Progressive batches: 25 records
- Seamless pagination for large datasets
### 🔍 Comprehensive Filtering
- **Parks**: 17+ filter parameters including geographic, temporal, and statistical filters
- **Rides**: 17+ filter parameters including roller coaster specs, performance metrics, and accessibility
### 📋 Dynamic Filter Metadata
- Real-time filter options based on current data
- Scoped metadata for contextual filtering
- Ranges and categorical options automatically generated
### ⚡ Performance Optimized
- 5-minute intelligent caching
- Strategic database indexing
- Optimized queries with prefetch_related
## Response Format
Both endpoints return consistent response structures:
```json
{
"parks": [...], // or "rides": [...]
"total_count": 123,
"strategy": "client_side", // or "server_side"
"has_more": false,
"next_offset": null,
"filter_metadata": {
"categorical": {
"countries": ["United States", "Canada", ...],
"categories": ["RC", "DR", "FR", ...],
// ... more options
},
"ranges": {
"opening_year": {"min": 1800, "max": 2025},
"rating": {"min": 1.0, "max": 10.0},
// ... more ranges
}
}
}
```
## Dependencies
- **curl**: Required for making HTTP requests
- **jq**: Optional but recommended for pretty JSON formatting
## Example Usage
### Basic Parks Query
```bash
curl "http://localhost:8000/api/v1/parks/hybrid/"
```
### Search for Disney Parks
```bash
curl "http://localhost:8000/api/v1/parks/hybrid/?search=disney"
```
### Filter Roller Coasters with Inversions
```bash
curl "http://localhost:8000/api/v1/rides/hybrid/?category=RC&has_inversions=true&height_ft_min=100"
```
### Get Filter Metadata
```bash
curl "http://localhost:8000/api/v1/parks/hybrid/filter-metadata/"
```
## Integration Guide
### Frontend Integration
1. Use filter metadata to build dynamic filter interfaces
2. Implement progressive loading for better UX
3. Handle both client-side and server-side strategies
4. Cache filter metadata to reduce API calls
### Performance Considerations
- Monitor response times and adjust thresholds as needed
- Use progressive loading for datasets >200 records
- Implement proper error handling for edge cases
- Consider implementing request debouncing for search
## Troubleshooting
### Server Not Running
```
❌ Server not available at http://localhost:8000
💡 Make sure to start the Django server first:
cd backend && uv run manage.py runserver 8000
```
### Missing jq
```
⚠️ jq not found - JSON responses will not be pretty-printed
```
Install jq for better output formatting:
```bash
# macOS
brew install jq
# Ubuntu/Debian
sudo apt-get install jq
```
## Next Steps
1. **Integrate into Frontend**: Use these endpoints in your React/Next.js application
2. **Build Filter UI**: Create dynamic filter interfaces using the metadata
3. **Implement Progressive Loading**: Handle large datasets efficiently
4. **Monitor Performance**: Track response times and optimize as needed
5. **Add Caching**: Implement client-side caching for better UX
---
🎢 **Happy filtering!** These endpoints provide a powerful, scalable foundation for building advanced search and filtering experiences in your theme park application.

View File

@@ -1,326 +0,0 @@
# Tailwind CSS v3 to v4 Migration Documentation
## Overview
This document details the complete migration process from Tailwind CSS v3 to v4 for the Django ThrillWiki project. The migration was performed on August 15, 2025, and includes all changes, configurations, and verification steps.
## Migration Summary
- **From**: Tailwind CSS v3.x
- **To**: Tailwind CSS v4.1.12
- **Project**: Django ThrillWiki (Django + Tailwind CSS integration)
- **Status**: ✅ Complete and Verified
- **Breaking Changes**: None (all styling preserved)
## Key Changes in Tailwind CSS v4
### 1. CSS Import Syntax
- **v3**: Used `@tailwind` directives
- **v4**: Uses single `@import "tailwindcss"` statement
### 2. Theme Configuration
- **v3**: Configuration in `tailwind.config.js`
- **v4**: CSS-first approach with `@theme` blocks
### 3. Deprecated Utilities
Multiple utility classes were renamed or deprecated in v4.
## Migration Steps Performed
### Step 1: Update Main CSS File
**File**: `static/css/src/input.css`
**Before (v3)**:
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Custom styles... */
```
**After (v4)**:
```css
@import "tailwindcss";
@theme {
--color-primary: #4f46e5;
--color-secondary: #e11d48;
--color-accent: #8b5cf6;
--font-family-sans: Poppins, sans-serif;
}
/* Custom styles... */
```
### Step 2: Theme Variable Migration
Migrated custom colors and fonts from `tailwind.config.js` to CSS variables in `@theme` block:
| Variable | Value | Description |
|----------|-------|-------------|
| `--color-primary` | `#4f46e5` | Indigo-600 (primary brand color) |
| `--color-secondary` | `#e11d48` | Rose-600 (secondary brand color) |
| `--color-accent` | `#8b5cf6` | Violet-500 (accent color) |
| `--font-family-sans` | `Poppins, sans-serif` | Primary font family |
### Step 3: Deprecated Utility Updates
#### Outline Utilities
- **Changed**: `outline-none``outline-hidden`
- **Files affected**: All template files, component CSS
#### Ring Utilities
- **Changed**: `ring``ring-3`
- **Reason**: Default ring width now requires explicit specification
#### Shadow Utilities
- **Changed**:
- `shadow-sm``shadow-xs`
- `shadow``shadow-sm`
- **Files affected**: Button components, card components
#### Opacity Utilities
- **Changed**: `bg-opacity-*` format → `color/opacity` format
- **Example**: `bg-blue-500 bg-opacity-50``bg-blue-500/50`
#### Flex Utilities
- **Changed**: `flex-shrink-0``shrink-0`
#### Important Modifier
- **Changed**: `!important``!` (shorter syntax)
- **Example**: `!outline-none``!outline-hidden`
### Step 4: Template File Updates
Updated the following template files with new utility classes:
#### Core Templates
- `templates/base.html`
- `templates/components/navbar.html`
- `templates/components/footer.html`
#### Page Templates
- `templates/parks/park_list.html`
- `templates/parks/park_detail.html`
- `templates/rides/ride_list.html`
- `templates/rides/ride_detail.html`
- `templates/companies/company_list.html`
- `templates/companies/company_detail.html`
#### Form Templates
- `templates/parks/park_form.html`
- `templates/rides/ride_form.html`
- `templates/companies/company_form.html`
#### Component Templates
- `templates/components/search_results.html`
- `templates/components/pagination.html`
### Step 5: Component CSS Updates
Updated custom component classes in `static/css/src/input.css`:
**Button Components**:
```css
.btn-primary {
@apply inline-flex items-center px-6 py-2.5 border border-transparent rounded-full shadow-md text-sm font-medium text-white bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90 focus:outline-hidden focus:ring-3 focus:ring-offset-2 focus:ring-primary/50 transform hover:scale-105 transition-all;
}
.btn-secondary {
@apply inline-flex items-center px-6 py-2.5 border border-gray-200 dark:border-gray-700 rounded-full shadow-md text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-hidden focus:ring-3 focus:ring-offset-2 focus:ring-primary/50 transform hover:scale-105 transition-all;
}
```
## Configuration Files
### Tailwind Config (Preserved for Reference)
**File**: `tailwind.config.js`
The original v3 configuration was preserved for reference but is no longer the primary configuration method:
```javascript
module.exports = {
content: [
'./templates/**/*.html',
'./static/js/**/*.js',
'./*/templates/**/*.html',
],
darkMode: 'class',
theme: {
extend: {
colors: {
primary: '#4f46e5',
secondary: '#e11d48',
accent: '#8b5cf6',
},
fontFamily: {
sans: ['Poppins', 'sans-serif'],
},
},
},
plugins: [
require('@tailwindcss/forms'),
require('@tailwindcss/typography'),
],
}
```
### Package.json Updates
No changes required to `package.json` as the Django-Tailwind package handles version management.
## Verification Steps
### 1. Build Process Verification
```bash
# Clean and rebuild CSS
lsof -ti :8000 | xargs kill -9
find . -type d -name "__pycache__" -exec rm -r {} +
uv run manage.py tailwind runserver
```
**Result**: ✅ Build successful, no errors
### 2. CSS Compilation Check
```bash
# Check compiled CSS size and content
ls -la static/css/tailwind.css
head -50 static/css/tailwind.css | grep -E "(primary|secondary|accent)"
```
**Result**: ✅ CSS properly compiled with theme variables
### 3. Server Response Check
```bash
curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/
```
**Result**: ✅ HTTP 200 - Server responding correctly
### 4. Visual Verification
- ✅ Primary colors (indigo) displaying correctly
- ✅ Secondary colors (rose) displaying correctly
- ✅ Accent colors (violet) displaying correctly
- ✅ Poppins font family loading correctly
- ✅ Button styling and interactions working
- ✅ Dark mode functionality preserved
- ✅ Responsive design intact
- ✅ All animations and transitions working
## Files Modified
### CSS Files
- `static/css/src/input.css` - ✅ Major updates (import syntax, theme variables, component classes)
### Template Files (Updated utility classes)
- `templates/base.html`
- `templates/components/navbar.html`
- `templates/components/footer.html`
- `templates/parks/park_list.html`
- `templates/parks/park_detail.html`
- `templates/parks/park_form.html`
- `templates/rides/ride_list.html`
- `templates/rides/ride_detail.html`
- `templates/rides/ride_form.html`
- `templates/companies/company_list.html`
- `templates/companies/company_detail.html`
- `templates/companies/company_form.html`
- `templates/components/search_results.html`
- `templates/components/pagination.html`
### Configuration Files (Preserved)
- `tailwind.config.js` - ✅ Preserved for reference
## Benefits of v4 Migration
### Performance Improvements
- Smaller CSS bundle size
- Faster compilation times
- Improved CSS-in-JS performance
### Developer Experience
- CSS-first configuration approach
- Better IDE support for theme variables
- Simplified import syntax
### Future Compatibility
- Modern CSS features support
- Better container queries support
- Enhanced dark mode capabilities
## Troubleshooting Guide
### Common Issues and Solutions
#### Issue: "Cannot apply unknown utility class"
**Solution**: Check if utility was renamed in v4 migration table above
#### Issue: Custom colors not working
**Solution**: Ensure `@theme` block is properly defined with CSS variables
#### Issue: Build errors
**Solution**: Run clean build process:
```bash
lsof -ti :8000 | xargs kill -9
find . -type d -name "__pycache__" -exec rm -r {} +
uv run manage.py tailwind runserver
```
## Rollback Plan
If rollback is needed:
1. **Restore CSS Import Syntax**:
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```
2. **Remove @theme Block**: Delete the `@theme` section from input.css
3. **Revert Utility Classes**: Use search/replace to revert utility class changes
4. **Downgrade Tailwind**: Update package to v3.x version
## Post-Migration Checklist
- [x] CSS compilation working
- [x] Development server running
- [x] All pages loading correctly
- [x] Colors displaying properly
- [x] Fonts loading correctly
- [x] Interactive elements working
- [x] Dark mode functioning
- [x] Responsive design intact
- [x] No console errors
- [x] Performance acceptable
## Future Considerations
### New v4 Features to Explore
- Enhanced container queries
- Improved dark mode utilities
- New color-mix() support
- Advanced CSS nesting
### Maintenance Notes
- Monitor for v4 updates and new features
- Consider migrating more configuration to CSS variables
- Evaluate new utility classes as they're released
## Contact and Support
For questions about this migration:
- Review this documentation
- Check Tailwind CSS v4 official documentation
- Consult the preserved `tailwind.config.js` for original settings
---
**Migration Completed**: August 15, 2025
**Tailwind Version**: v4.1.12
**Status**: Production Ready ✅

View File

@@ -1,80 +0,0 @@
# Tailwind CSS v4 Quick Reference Guide
## Common v3 → v4 Utility Migrations
| v3 Utility | v4 Utility | Notes |
|------------|------------|-------|
| `outline-none` | `outline-hidden` | Accessibility improvement |
| `ring` | `ring-3` | Must specify ring width |
| `shadow-sm` | `shadow-xs` | Renamed for consistency |
| `shadow` | `shadow-sm` | Renamed for consistency |
| `flex-shrink-0` | `shrink-0` | Shortened syntax |
| `bg-blue-500 bg-opacity-50` | `bg-blue-500/50` | New opacity syntax |
| `text-gray-700 text-opacity-75` | `text-gray-700/75` | New opacity syntax |
| `!outline-none` | `!outline-hidden` | Updated important syntax |
## Theme Variables (Available in CSS)
```css
/* Colors */
var(--color-primary) /* #4f46e5 - Indigo-600 */
var(--color-secondary) /* #e11d48 - Rose-600 */
var(--color-accent) /* #8b5cf6 - Violet-500 */
/* Fonts */
var(--font-family-sans) /* Poppins, sans-serif */
```
## Usage in Templates
### Before (v3)
```html
<button class="outline-none ring hover:ring-2 shadow-sm bg-blue-500 bg-opacity-75">
Click me
</button>
```
### After (v4)
```html
<button class="outline-hidden ring-3 hover:ring-2 shadow-xs bg-blue-500/75">
Click me
</button>
```
## Development Commands
### Start Development Server
```bash
lsof -ti :8000 | xargs kill -9; find . -type d -name "__pycache__" -exec rm -r {} +; uv run manage.py tailwind runserver
```
### Force CSS Rebuild
```bash
uv run manage.py tailwind build
```
## New v4 Features
- **CSS-first configuration** via `@theme` blocks
- **Improved opacity syntax** with `/` operator
- **Better color-mix() support**
- **Enhanced dark mode utilities**
- **Faster compilation**
## Troubleshooting
### Unknown utility class error
1. Check if utility was renamed (see table above)
2. Verify custom theme variables are defined
3. Run clean build process
### Colors not working
1. Ensure `@theme` block exists in `static/css/src/input.css`
2. Check CSS variable names match usage
3. Verify CSS compilation completed
## Resources
- [Full Migration Documentation](./TAILWIND_V4_MIGRATION.md)
- [Tailwind CSS v4 Official Docs](https://tailwindcss.com/docs)
- [Django-Tailwind Package](https://django-tailwind.readthedocs.io/)

View File

@@ -1,470 +0,0 @@
# ThrillWiki API Documentation v1
## Complete Frontend Developer Reference
**Base URL**: `/api/v1/`
**Authentication**: JWT Bearer tokens
**Content-Type**: `application/json`
---
## 🔐 Authentication Endpoints (`/api/v1/auth/`)
### Core Authentication
- **POST** `/auth/login/` - User login with username/email and password
- **POST** `/auth/signup/` - User registration (email verification required)
- **POST** `/auth/logout/` - Logout current user (blacklist refresh token)
- **GET** `/auth/user/` - Get current authenticated user information
- **POST** `/auth/status/` - Check authentication status
### Password Management
- **POST** `/auth/password/reset/` - Request password reset email
- **POST** `/auth/password/change/` - Change current user's password
### Email Verification
- **GET** `/auth/verify-email/<token>/` - Verify email with token
- **POST** `/auth/resend-verification/` - Resend email verification
### Social Authentication
- **GET** `/auth/social/providers/` - Get available social auth providers
- **GET** `/auth/social/providers/available/` - Get available social providers list
- **GET** `/auth/social/connected/` - Get user's connected social providers
- **POST** `/auth/social/connect/<provider>/` - Connect social provider (Google, Discord)
- **POST** `/auth/social/disconnect/<provider>/` - Disconnect social provider
- **GET** `/auth/social/status/` - Get comprehensive social auth status
- **POST** `/auth/social/` - Social auth endpoints (dj-rest-auth)
### JWT Token Management
- **POST** `/auth/token/refresh/` - Refresh JWT access token
---
## 🏞️ Parks API Endpoints (`/api/v1/parks/`)
### Core CRUD Operations
- **GET** `/parks/` - List parks with comprehensive filtering and pagination
- **POST** `/parks/` - Create new park (authenticated users)
- **GET** `/parks/<pk>/` - Get park details (supports ID or slug)
- **PATCH** `/parks/<pk>/` - Update park (partial update)
- **PUT** `/parks/<pk>/` - Update park (full update)
- **DELETE** `/parks/<pk>/` - Delete park
### Filtering & Search
- **GET** `/parks/filter-options/` - Get available filter options
- **GET** `/parks/search/companies/?q=<query>` - Search companies/operators
- **GET** `/parks/search-suggestions/?q=<query>` - Get park search suggestions
- **GET** `/parks/hybrid/` - Hybrid park filtering with advanced options
- **GET** `/parks/hybrid/filter-metadata/` - Get filter metadata for hybrid filtering
### Park Photos Management
- **GET** `/parks/<park_pk>/photos/` - List park photos
- **POST** `/parks/<park_pk>/photos/` - Upload park photo
- **GET** `/parks/<park_pk>/photos/<id>/` - Get park photo details
- **PATCH** `/parks/<park_pk>/photos/<id>/` - Update park photo
- **DELETE** `/parks/<park_pk>/photos/<id>/` - Delete park photo
- **POST** `/parks/<park_pk>/photos/<id>/set_primary/` - Set photo as primary
- **POST** `/parks/<park_pk>/photos/bulk_approve/` - Bulk approve/reject photos (admin)
- **GET** `/parks/<park_pk>/photos/stats/` - Get park photo statistics
### Park Settings
- **GET** `/parks/<pk>/image-settings/` - Get park image settings
- **POST** `/parks/<pk>/image-settings/` - Update park image settings
#### Park Filtering Parameters (24 total):
- **Pagination**: `page`, `page_size`
- **Search**: `search`
- **Location**: `continent`, `country`, `state`, `city`
- **Attributes**: `park_type`, `status`
- **Companies**: `operator_id`, `operator_slug`, `property_owner_id`, `property_owner_slug`
- **Ratings**: `min_rating`, `max_rating`
- **Ride Counts**: `min_ride_count`, `max_ride_count`
- **Opening Year**: `opening_year`, `min_opening_year`, `max_opening_year`
- **Roller Coasters**: `has_roller_coasters`, `min_roller_coaster_count`, `max_roller_coaster_count`
- **Ordering**: `ordering`
---
## 🎢 Rides API Endpoints (`/api/v1/rides/`)
### Core CRUD Operations
- **GET** `/rides/` - List rides with comprehensive filtering
- **POST** `/rides/` - Create new ride
- **GET** `/rides/<pk>/` - Get ride details
- **PATCH** `/rides/<pk>/` - Update ride (partial)
- **PUT** `/rides/<pk>/` - Update ride (full)
- **DELETE** `/rides/<pk>/` - Delete ride
### Filtering & Search
- **GET** `/rides/filter-options/` - Get available filter options
- **GET** `/rides/search/companies/?q=<query>` - Search ride companies
- **GET** `/rides/search/ride-models/?q=<query>` - Search ride models
- **GET** `/rides/search-suggestions/?q=<query>` - Get ride search suggestions
- **GET** `/rides/hybrid/` - Hybrid ride filtering
- **GET** `/rides/hybrid/filter-metadata/` - Get ride filter metadata
### Ride Photos Management
- **GET** `/rides/<ride_pk>/photos/` - List ride photos
- **POST** `/rides/<ride_pk>/photos/` - Upload ride photo
- **GET** `/rides/<ride_pk>/photos/<id>/` - Get ride photo details
- **PATCH** `/rides/<ride_pk>/photos/<id>/` - Update ride photo
- **DELETE** `/rides/<ride_pk>/photos/<id>/` - Delete ride photo
- **POST** `/rides/<ride_pk>/photos/<id>/set_primary/` - Set photo as primary
### Ride Manufacturers
- **GET** `/rides/manufacturers/<manufacturer_slug>/` - Manufacturer-specific endpoints
### Ride Settings
- **GET** `/rides/<pk>/image-settings/` - Get ride image settings
- **POST** `/rides/<pk>/image-settings/` - Update ride image settings
---
## 👤 User Accounts API (`/api/v1/accounts/`)
### User Management (Admin)
- **DELETE** `/accounts/users/<user_id>/delete/` - Delete user while preserving submissions
- **GET** `/accounts/users/<user_id>/deletion-check/` - Check user deletion eligibility
### Self-Service Account Management
- **POST** `/accounts/delete-account/request/` - Request account deletion
- **POST** `/accounts/delete-account/verify/` - Verify account deletion
- **POST** `/accounts/delete-account/cancel/` - Cancel account deletion
### User Profile Management
- **GET** `/accounts/profile/` - Get user profile
- **PATCH** `/accounts/profile/account/` - Update user account info
- **PATCH** `/accounts/profile/update/` - Update user profile
### User Preferences
- **GET** `/accounts/preferences/` - Get user preferences
- **PATCH** `/accounts/preferences/update/` - Update user preferences
- **PATCH** `/accounts/preferences/theme/` - Update theme preference
### Settings Management
- **GET** `/accounts/settings/notifications/` - Get notification settings
- **PATCH** `/accounts/settings/notifications/update/` - Update notification settings
- **GET** `/accounts/settings/privacy/` - Get privacy settings
- **PATCH** `/accounts/settings/privacy/update/` - Update privacy settings
- **GET** `/accounts/settings/security/` - Get security settings
- **PATCH** `/accounts/settings/security/update/` - Update security settings
### User Statistics & Lists
- **GET** `/accounts/statistics/` - Get user statistics
- **GET** `/accounts/top-lists/` - Get user's top lists
- **POST** `/accounts/top-lists/create/` - Create new top list
- **PATCH** `/accounts/top-lists/<list_id>/` - Update top list
- **DELETE** `/accounts/top-lists/<list_id>/delete/` - Delete top list
### Notifications
- **GET** `/accounts/notifications/` - Get user notifications
- **POST** `/accounts/notifications/mark-read/` - Mark notifications as read
- **GET** `/accounts/notification-preferences/` - Get notification preferences
- **PATCH** `/accounts/notification-preferences/update/` - Update notification preferences
### Avatar Management
- **POST** `/accounts/profile/avatar/upload/` - Upload avatar
- **POST** `/accounts/profile/avatar/save/` - Save avatar image
- **DELETE** `/accounts/profile/avatar/delete/` - Delete avatar
---
## 🗺️ Maps API (`/api/v1/maps/`)
### Location Data
- **GET** `/maps/locations/` - Get map locations data
- **GET** `/maps/locations/<location_type>/<location_id>/` - Get location details
- **GET** `/maps/search/` - Search locations on map
- **GET** `/maps/bounds/` - Query locations within bounds
### Map Services
- **GET** `/maps/stats/` - Get map service statistics
- **GET** `/maps/cache/` - Get map cache information
- **POST** `/maps/cache/invalidate/` - Invalidate map cache
---
## 🔍 Core Search API (`/api/v1/core/`)
### Entity Search
- **GET** `/core/entities/search/` - Fuzzy search for entities
- **GET** `/core/entities/not-found/` - Handle entity not found
- **GET** `/core/entities/suggestions/` - Quick entity suggestions
---
## 📧 Email API (`/api/v1/email/`)
### Email Services
- **POST** `/email/send/` - Send email
---
## 📜 History API (`/api/v1/history/`)
### Park History
- **GET** `/history/parks/<park_slug>/` - Get park history
- **GET** `/history/parks/<park_slug>/detail/` - Get detailed park history
### Ride History
- **GET** `/history/parks/<park_slug>/rides/<ride_slug>/` - Get ride history
- **GET** `/history/parks/<park_slug>/rides/<ride_slug>/detail/` - Get detailed ride history
### Unified Timeline
- **GET** `/history/timeline/` - Get unified history timeline
---
## 📈 System & Analytics APIs
### Health Checks
- **GET** `/api/v1/health/` - Comprehensive health check
- **GET** `/api/v1/health/simple/` - Simple health check
- **GET** `/api/v1/health/performance/` - Performance metrics
### Trending & Discovery
- **GET** `/api/v1/trending/` - Get trending content
- **GET** `/api/v1/new-content/` - Get new content
- **POST** `/api/v1/trending/calculate/` - Trigger trending calculation
### Statistics
- **GET** `/api/v1/stats/` - Get system statistics
- **POST** `/api/v1/stats/recalculate/` - Recalculate statistics
### Reviews
- **GET** `/api/v1/reviews/latest/` - Get latest reviews
### Rankings
- **GET** `/api/v1/rankings/` - Get ride rankings with filtering
- **GET** `/api/v1/rankings/<ride_slug>/` - Get detailed ranking for specific ride
- **GET** `/api/v1/rankings/<ride_slug>/history/` - Get ranking history for ride
- **GET** `/api/v1/rankings/<ride_slug>/comparisons/` - Get head-to-head comparisons
- **GET** `/api/v1/rankings/statistics/` - Get ranking system statistics
- **POST** `/api/v1/rankings/calculate/` - Trigger ranking calculation (admin)
#### Rankings Filtering Parameters:
- **category**: Filter by ride category (RC, DR, FR, WR, TR, OT)
- **min_riders**: Minimum number of mutual riders required
- **park**: Filter by park slug
- **ordering**: Order results (rank, -rank, winning_percentage, -winning_percentage)
---
## 🛡️ Moderation API (`/api/v1/moderation/`)
### Moderation Reports
- **GET** `/moderation/reports/` - List all moderation reports
- **POST** `/moderation/reports/` - Create new moderation report
- **GET** `/moderation/reports/<id>/` - Get specific report details
- **PUT** `/moderation/reports/<id>/` - Update moderation report
- **PATCH** `/moderation/reports/<id>/` - Partial update report
- **DELETE** `/moderation/reports/<id>/` - Delete moderation report
- **POST** `/moderation/reports/<id>/assign/` - Assign report to moderator
- **POST** `/moderation/reports/<id>/resolve/` - Resolve moderation report
- **GET** `/moderation/reports/stats/` - Get report statistics
### Moderation Queue
- **GET** `/moderation/queue/` - List moderation queue items
- **POST** `/moderation/queue/` - Create queue item
- **GET** `/moderation/queue/<id>/` - Get specific queue item
- **PUT** `/moderation/queue/<id>/` - Update queue item
- **PATCH** `/moderation/queue/<id>/` - Partial update queue item
- **DELETE** `/moderation/queue/<id>/` - Delete queue item
- **POST** `/moderation/queue/<id>/assign/` - Assign queue item to moderator
- **POST** `/moderation/queue/<id>/unassign/` - Unassign queue item
- **POST** `/moderation/queue/<id>/complete/` - Complete queue item
- **GET** `/moderation/queue/my_queue/` - Get current user's queue items
### Moderation Actions
- **GET** `/moderation/actions/` - List all moderation actions
- **POST** `/moderation/actions/` - Create new moderation action
- **GET** `/moderation/actions/<id>/` - Get specific action details
- **PUT** `/moderation/actions/<id>/` - Update moderation action
- **PATCH** `/moderation/actions/<id>/` - Partial update action
- **DELETE** `/moderation/actions/<id>/` - Delete moderation action
- **POST** `/moderation/actions/<id>/deactivate/` - Deactivate action
- **GET** `/moderation/actions/active/` - Get active moderation actions
- **GET** `/moderation/actions/expired/` - Get expired moderation actions
### Bulk Operations
- **GET** `/moderation/bulk-operations/` - List bulk moderation operations
- **POST** `/moderation/bulk-operations/` - Create bulk operation
- **GET** `/moderation/bulk-operations/<id>/` - Get bulk operation details
- **PUT** `/moderation/bulk-operations/<id>/` - Update bulk operation
- **PATCH** `/moderation/bulk-operations/<id>/` - Partial update operation
- **DELETE** `/moderation/bulk-operations/<id>/` - Delete bulk operation
- **POST** `/moderation/bulk-operations/<id>/cancel/` - Cancel bulk operation
- **POST** `/moderation/bulk-operations/<id>/retry/` - Retry failed operation
- **GET** `/moderation/bulk-operations/<id>/logs/` - Get operation logs
- **GET** `/moderation/bulk-operations/running/` - Get running operations
### User Moderation
- **GET** `/moderation/users/<id>/` - Get user moderation profile
- **POST** `/moderation/users/<id>/moderate/` - Take moderation action against user
- **GET** `/moderation/users/search/` - Search users for moderation
- **GET** `/moderation/users/stats/` - Get user moderation statistics
---
## 🏗️ Ride Manufacturers & Models (`/api/v1/rides/manufacturers/<manufacturer_slug>/`)
### Ride Models
- **GET** `/rides/manufacturers/<manufacturer_slug>/` - List ride models by manufacturer
- **POST** `/rides/manufacturers/<manufacturer_slug>/` - Create new ride model
- **GET** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/` - Get ride model details
- **PATCH** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/` - Update ride model
- **DELETE** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/` - Delete ride model
### Model Search & Filtering
- **GET** `/rides/manufacturers/<manufacturer_slug>/search/` - Search ride models
- **GET** `/rides/manufacturers/<manufacturer_slug>/filter-options/` - Get filter options
- **GET** `/rides/manufacturers/<manufacturer_slug>/stats/` - Get manufacturer statistics
### Model Variants
- **GET** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/variants/` - List model variants
- **POST** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/variants/` - Create variant
- **GET** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/variants/<id>/` - Get variant details
- **PATCH** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/variants/<id>/` - Update variant
- **DELETE** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/variants/<id>/` - Delete variant
### Technical Specifications
- **GET** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/technical-specs/` - List technical specs
- **POST** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/technical-specs/` - Create technical spec
- **GET** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/technical-specs/<id>/` - Get spec details
- **PATCH** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/technical-specs/<id>/` - Update spec
- **DELETE** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/technical-specs/<id>/` - Delete spec
### Model Photos
- **GET** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/photos/` - List model photos
- **POST** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/photos/` - Upload model photo
- **GET** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/photos/<id>/` - Get photo details
- **PATCH** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/photos/<id>/` - Update photo
- **DELETE** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/photos/<id>/` - Delete photo
---
## 🖼️ Media Management
### Cloudflare Images
- **ALL** `/api/v1/cloudflare-images/` - Cloudflare Images toolkit endpoints
---
## 📚 API Documentation
### Interactive Documentation
- **GET** `/api/schema/` - OpenAPI schema
- **GET** `/api/docs/` - Swagger UI documentation
- **GET** `/api/redoc/` - ReDoc documentation
---
## 🔧 Common Request/Response Patterns
### Authentication Headers
```javascript
headers: {
'Authorization': 'Bearer <access_token>',
'Content-Type': 'application/json'
}
```
### Pagination Response
```json
{
"count": 100,
"next": "http://api.example.com/api/v1/endpoint/?page=2",
"previous": null,
"results": [...]
}
```
### Error Response Format
```json
{
"error": "Error message",
"error_code": "SPECIFIC_ERROR_CODE",
"details": {...},
"suggestions": ["suggestion1", "suggestion2"]
}
```
### Success Response Format
```json
{
"success": true,
"message": "Operation completed successfully",
"data": {...}
}
```
---
## 📝 Key Data Models
### User
- `id`, `username`, `email`, `display_name`, `date_joined`, `is_active`, `avatar_url`
### Park
- `id`, `name`, `slug`, `description`, `location`, `operator`, `park_type`, `status`, `opening_year`
### Ride
- `id`, `name`, `slug`, `park`, `category`, `manufacturer`, `model`, `opening_year`, `status`
### Photo (Park/Ride)
- `id`, `image`, `caption`, `photo_type`, `uploaded_by`, `is_primary`, `is_approved`, `created_at`
### Review
- `id`, `user`, `content_object`, `rating`, `title`, `content`, `created_at`, `updated_at`
---
## 🚨 Important Notes
1. **Authentication Required**: Most endpoints require JWT authentication
2. **Permissions**: Admin endpoints require staff/superuser privileges
3. **Rate Limiting**: May be implemented on certain endpoints
4. **File Uploads**: Use `multipart/form-data` for photo uploads
5. **Pagination**: Most list endpoints support pagination with `page` and `page_size` parameters
6. **Filtering**: Parks and rides support extensive filtering options
7. **Cloudflare Images**: Media files are handled through Cloudflare Images service
8. **Email Verification**: New users must verify email before full access
---
## 📖 Usage Examples
### Authentication Flow
```javascript
// Login
const login = await fetch('/api/v1/auth/login/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'user@example.com', password: 'password' })
});
// Use tokens from response
const { access, refresh } = await login.json();
```
### Fetch Parks with Filtering
```javascript
const parks = await fetch('/api/v1/parks/?continent=NA&min_rating=4.0&page=1', {
headers: { 'Authorization': `Bearer ${access_token}` }
});
```
### Upload Park Photo
```javascript
const formData = new FormData();
formData.append('image', file);
formData.append('caption', 'Beautiful park entrance');
const photo = await fetch('/api/v1/parks/123/photos/', {
method: 'POST',
headers: { 'Authorization': `Bearer ${access_token}` },
body: formData
});
```
---
This documentation covers all available API endpoints in the ThrillWiki v1 API. For detailed request/response schemas, parameter validation, and interactive testing, visit `/api/docs/` when the development server is running.

View File

@@ -1,649 +0,0 @@
#!/bin/bash
# ThrillWiki API Endpoints - Complete Curl Commands
# Generated from comprehensive URL analysis
# Base URL - adjust as needed for your environment
BASE_URL="http://localhost:8000"
# Command line options
SKIP_AUTH=false
ONLY_AUTH=false
SKIP_DOCS=false
HELP=false
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
--skip-auth)
SKIP_AUTH=true
shift
;;
--only-auth)
ONLY_AUTH=true
shift
;;
--skip-docs)
SKIP_DOCS=true
shift
;;
--base-url)
BASE_URL="$2"
shift 2
;;
--help|-h)
HELP=true
shift
;;
*)
echo "Unknown option: $1"
echo "Use --help for usage information"
exit 1
;;
esac
done
# Show help
if [ "$HELP" = true ]; then
echo "ThrillWiki API Endpoints Test Suite"
echo ""
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " --skip-auth Skip endpoints that require authentication"
echo " --only-auth Only test endpoints that require authentication"
echo " --skip-docs Skip API documentation endpoints (schema, swagger, redoc)"
echo " --base-url URL Set custom base URL (default: http://localhost:8000)"
echo " --help, -h Show this help message"
echo ""
echo "Examples:"
echo " $0 # Test all endpoints"
echo " $0 --skip-auth # Test only public endpoints"
echo " $0 --only-auth # Test only authenticated endpoints"
echo " $0 --skip-docs --skip-auth # Test only public non-documentation endpoints"
echo " $0 --base-url https://api.example.com # Use custom base URL"
exit 0
fi
# Validate conflicting options
if [ "$SKIP_AUTH" = true ] && [ "$ONLY_AUTH" = true ]; then
echo "Error: --skip-auth and --only-auth cannot be used together"
exit 1
fi
echo "=== ThrillWiki API Endpoints Test Suite ==="
echo "Base URL: $BASE_URL"
if [ "$SKIP_AUTH" = true ]; then
echo "Mode: Public endpoints only (skipping authentication required)"
elif [ "$ONLY_AUTH" = true ]; then
echo "Mode: Authenticated endpoints only"
else
echo "Mode: All endpoints"
fi
if [ "$SKIP_DOCS" = true ]; then
echo "Skipping: API documentation endpoints"
fi
echo ""
# Helper function to check if we should run an endpoint
should_run_endpoint() {
local requires_auth=$1
local is_docs=$2
# Skip docs if requested
if [ "$SKIP_DOCS" = true ] && [ "$is_docs" = true ]; then
return 1
fi
# Skip auth endpoints if requested
if [ "$SKIP_AUTH" = true ] && [ "$requires_auth" = true ]; then
return 1
fi
# Only run auth endpoints if requested
if [ "$ONLY_AUTH" = true ] && [ "$requires_auth" = false ]; then
return 1
fi
return 0
}
# Counter for endpoint numbering
ENDPOINT_NUM=1
# ============================================================================
# AUTHENTICATION ENDPOINTS (/api/v1/auth/)
# ============================================================================
if should_run_endpoint false false || should_run_endpoint true false; then
echo "=== AUTHENTICATION ENDPOINTS ==="
fi
if should_run_endpoint false false; then
echo "$ENDPOINT_NUM. Login"
curl -X POST "$BASE_URL/api/v1/auth/login/" \
-H "Content-Type: application/json" \
-d '{"username": "testuser", "password": "testpass"}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Signup"
curl -X POST "$BASE_URL/api/v1/auth/signup/" \
-H "Content-Type: application/json" \
-d '{"username": "newuser", "email": "test@example.com", "password": "newpass123"}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Logout"
curl -X POST "$BASE_URL/api/v1/auth/logout/" \
-H "Content-Type: application/json"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Password Reset"
curl -X POST "$BASE_URL/api/v1/auth/password/reset/" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Social Providers"
curl -X GET "$BASE_URL/api/v1/auth/providers/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Auth Status"
curl -X GET "$BASE_URL/api/v1/auth/status/"
((ENDPOINT_NUM++))
fi
if should_run_endpoint true false; then
echo -e "\n$ENDPOINT_NUM. Current User"
curl -X GET "$BASE_URL/api/v1/auth/user/" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Password Change"
curl -X POST "$BASE_URL/api/v1/auth/password/change/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{"old_password": "oldpass", "new_password": "newpass123"}'
((ENDPOINT_NUM++))
fi
# ============================================================================
# HEALTH CHECK ENDPOINTS (/api/v1/health/)
# ============================================================================
if should_run_endpoint false false; then
echo -e "\n\n=== HEALTH CHECK ENDPOINTS ==="
echo "$ENDPOINT_NUM. Health Check"
curl -X GET "$BASE_URL/api/v1/health/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Simple Health"
curl -X GET "$BASE_URL/api/v1/health/simple/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Performance Metrics"
curl -X GET "$BASE_URL/api/v1/health/performance/"
((ENDPOINT_NUM++))
fi
# ============================================================================
# TRENDING SYSTEM ENDPOINTS (/api/v1/trending/)
# ============================================================================
if should_run_endpoint false false; then
echo -e "\n\n=== TRENDING SYSTEM ENDPOINTS ==="
echo "$ENDPOINT_NUM. Trending Content"
curl -X GET "$BASE_URL/api/v1/trending/content/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. New Content"
curl -X GET "$BASE_URL/api/v1/trending/new/"
((ENDPOINT_NUM++))
fi
# ============================================================================
# STATISTICS ENDPOINTS (/api/v1/stats/)
# ============================================================================
if should_run_endpoint false false || should_run_endpoint true false; then
echo -e "\n\n=== STATISTICS ENDPOINTS ==="
fi
if should_run_endpoint false false; then
echo "$ENDPOINT_NUM. Statistics"
curl -X GET "$BASE_URL/api/v1/stats/"
((ENDPOINT_NUM++))
fi
if should_run_endpoint true false; then
echo -e "\n$ENDPOINT_NUM. Recalculate Statistics"
curl -X POST "$BASE_URL/api/v1/stats/recalculate/" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"
((ENDPOINT_NUM++))
fi
# ============================================================================
# RANKING SYSTEM ENDPOINTS (/api/v1/rankings/)
# ============================================================================
if should_run_endpoint false false || should_run_endpoint true false; then
echo -e "\n\n=== RANKING SYSTEM ENDPOINTS ==="
fi
if should_run_endpoint false false; then
echo "$ENDPOINT_NUM. List Rankings"
curl -X GET "$BASE_URL/api/v1/rankings/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. List Rankings with Filters"
curl -X GET "$BASE_URL/api/v1/rankings/?category=RC&min_riders=10&ordering=rank"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Ranking Detail"
curl -X GET "$BASE_URL/api/v1/rankings/ride-slug-here/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Ranking History"
curl -X GET "$BASE_URL/api/v1/rankings/ride-slug-here/history/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Ranking Statistics"
curl -X GET "$BASE_URL/api/v1/rankings/statistics/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Ranking Comparisons"
curl -X GET "$BASE_URL/api/v1/rankings/ride-slug-here/comparisons/"
((ENDPOINT_NUM++))
fi
if should_run_endpoint true false; then
echo -e "\n$ENDPOINT_NUM. Trigger Ranking Calculation"
curl -X POST "$BASE_URL/api/v1/rankings/calculate/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{"category": "RC"}'
((ENDPOINT_NUM++))
fi
# ============================================================================
# PARKS API ENDPOINTS (/api/v1/parks/)
# ============================================================================
if should_run_endpoint false false || should_run_endpoint true false; then
echo -e "\n\n=== PARKS API ENDPOINTS ==="
fi
if should_run_endpoint false false; then
echo "$ENDPOINT_NUM. List Parks"
curl -X GET "$BASE_URL/api/v1/parks/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Park Filter Options"
curl -X GET "$BASE_URL/api/v1/parks/filter-options/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Park Company Search"
curl -X GET "$BASE_URL/api/v1/parks/search/companies/?q=disney"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Park Search Suggestions"
curl -X GET "$BASE_URL/api/v1/parks/search-suggestions/?q=magic"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Park Detail"
curl -X GET "$BASE_URL/api/v1/parks/1/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. List Park Photos"
curl -X GET "$BASE_URL/api/v1/parks/1/photos/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Park Photo Detail"
curl -X GET "$BASE_URL/api/v1/parks/1/photos/1/"
((ENDPOINT_NUM++))
fi
if should_run_endpoint true false; then
echo -e "\n$ENDPOINT_NUM. Create Park"
curl -X POST "$BASE_URL/api/v1/parks/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{"name": "Test Park", "location": "Test City"}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Update Park"
curl -X PUT "$BASE_URL/api/v1/parks/1/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{"name": "Updated Park Name"}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Delete Park"
curl -X DELETE "$BASE_URL/api/v1/parks/1/" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Create Park Photo"
curl -X POST "$BASE_URL/api/v1/parks/1/photos/" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-F "image=@/path/to/photo.jpg" \
-F "caption=Test photo"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Update Park Photo"
curl -X PUT "$BASE_URL/api/v1/parks/1/photos/1/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{"caption": "Updated caption"}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Delete Park Photo"
curl -X DELETE "$BASE_URL/api/v1/parks/1/photos/1/" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"
((ENDPOINT_NUM++))
fi
# ============================================================================
# RIDES API ENDPOINTS (/api/v1/rides/)
# ============================================================================
if should_run_endpoint false false || should_run_endpoint true false; then
echo -e "\n\n=== RIDES API ENDPOINTS ==="
fi
if should_run_endpoint false false; then
echo "$ENDPOINT_NUM. List Rides"
curl -X GET "$BASE_URL/api/v1/rides/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Ride Filter Options"
curl -X GET "$BASE_URL/api/v1/rides/filter-options/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Ride Company Search"
curl -X GET "$BASE_URL/api/v1/rides/search/companies/?q=intamin"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Ride Model Search"
curl -X GET "$BASE_URL/api/v1/rides/search/ride-models/?q=giga"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Ride Search Suggestions"
curl -X GET "$BASE_URL/api/v1/rides/search-suggestions/?q=millennium"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Ride Detail"
curl -X GET "$BASE_URL/api/v1/rides/1/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. List Ride Photos"
curl -X GET "$BASE_URL/api/v1/rides/1/photos/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Ride Photo Detail"
curl -X GET "$BASE_URL/api/v1/rides/1/photos/1/"
((ENDPOINT_NUM++))
fi
if should_run_endpoint true false; then
echo -e "\n$ENDPOINT_NUM. Create Ride"
curl -X POST "$BASE_URL/api/v1/rides/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{"name": "Test Coaster", "category": "RC", "park": 1}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Update Ride"
curl -X PUT "$BASE_URL/api/v1/rides/1/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{"name": "Updated Ride Name"}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Delete Ride"
curl -X DELETE "$BASE_URL/api/v1/rides/1/" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Create Ride Photo"
curl -X POST "$BASE_URL/api/v1/rides/1/photos/" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-F "image=@/path/to/photo.jpg" \
-F "caption=Test ride photo"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Update Ride Photo"
curl -X PUT "$BASE_URL/api/v1/rides/1/photos/1/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{"caption": "Updated ride photo caption"}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Delete Ride Photo"
curl -X DELETE "$BASE_URL/api/v1/rides/1/photos/1/" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"
((ENDPOINT_NUM++))
fi
# ============================================================================
# ACCOUNTS API ENDPOINTS (/api/v1/accounts/)
# ============================================================================
if should_run_endpoint false false || should_run_endpoint true false; then
echo -e "\n\n=== ACCOUNTS API ENDPOINTS ==="
fi
if should_run_endpoint false false; then
echo "$ENDPOINT_NUM. List User Profiles"
curl -X GET "$BASE_URL/api/v1/accounts/profiles/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. User Profile Detail"
curl -X GET "$BASE_URL/api/v1/accounts/profiles/1/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. List Top Lists"
curl -X GET "$BASE_URL/api/v1/accounts/toplists/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Top List Detail"
curl -X GET "$BASE_URL/api/v1/accounts/toplists/1/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. List Top List Items"
curl -X GET "$BASE_URL/api/v1/accounts/toplist-items/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Top List Item Detail"
curl -X GET "$BASE_URL/api/v1/accounts/toplist-items/1/"
((ENDPOINT_NUM++))
fi
if should_run_endpoint true false; then
echo -e "\n$ENDPOINT_NUM. Update User Profile"
curl -X PUT "$BASE_URL/api/v1/accounts/profiles/1/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{"bio": "Updated bio"}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Create Top List"
curl -X POST "$BASE_URL/api/v1/accounts/toplists/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{"name": "My Top Coasters", "description": "My favorite roller coasters"}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Update Top List"
curl -X PUT "$BASE_URL/api/v1/accounts/toplists/1/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{"name": "Updated Top List Name"}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Delete Top List"
curl -X DELETE "$BASE_URL/api/v1/accounts/toplists/1/" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Create Top List Item"
curl -X POST "$BASE_URL/api/v1/accounts/toplist-items/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{"toplist": 1, "ride": 1, "position": 1}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Update Top List Item"
curl -X PUT "$BASE_URL/api/v1/accounts/toplist-items/1/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{"position": 2}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Delete Top List Item"
curl -X DELETE "$BASE_URL/api/v1/accounts/toplist-items/1/" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"
((ENDPOINT_NUM++))
fi
# ============================================================================
# HISTORY API ENDPOINTS (/api/v1/history/)
# ============================================================================
if should_run_endpoint false false; then
echo -e "\n\n=== HISTORY API ENDPOINTS ==="
echo "$ENDPOINT_NUM. Park History List"
curl -X GET "$BASE_URL/api/v1/history/parks/park-slug/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Park History Detail"
curl -X GET "$BASE_URL/api/v1/history/parks/park-slug/detail/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Ride History List"
curl -X GET "$BASE_URL/api/v1/history/parks/park-slug/rides/ride-slug/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Ride History Detail"
curl -X GET "$BASE_URL/api/v1/history/parks/park-slug/rides/ride-slug/detail/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Unified Timeline"
curl -X GET "$BASE_URL/api/v1/history/timeline/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Unified Timeline Detail"
curl -X GET "$BASE_URL/api/v1/history/timeline/1/"
((ENDPOINT_NUM++))
fi
# ============================================================================
# EMAIL API ENDPOINTS (/api/v1/email/)
# ============================================================================
if should_run_endpoint true false; then
echo -e "\n\n=== EMAIL API ENDPOINTS ==="
echo "$ENDPOINT_NUM. Send Email"
curl -X POST "$BASE_URL/api/v1/email/send/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{"to": "recipient@example.com", "subject": "Test", "message": "Test message"}'
((ENDPOINT_NUM++))
fi
# ============================================================================
# CORE API ENDPOINTS (/api/v1/core/)
# ============================================================================
if should_run_endpoint false false; then
echo -e "\n\n=== CORE API ENDPOINTS ==="
echo "$ENDPOINT_NUM. Entity Fuzzy Search"
curl -X GET "$BASE_URL/api/v1/core/entities/search/?q=disney"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Entity Not Found"
curl -X POST "$BASE_URL/api/v1/core/entities/not-found/" \
-H "Content-Type: application/json" \
-d '{"query": "nonexistent park", "type": "park"}'
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Entity Suggestions"
curl -X GET "$BASE_URL/api/v1/core/entities/suggestions/?q=magic"
((ENDPOINT_NUM++))
fi
# ============================================================================
# MAPS API ENDPOINTS (/api/v1/maps/)
# ============================================================================
if should_run_endpoint false false || should_run_endpoint true false; then
echo -e "\n\n=== MAPS API ENDPOINTS ==="
fi
if should_run_endpoint false false; then
echo "$ENDPOINT_NUM. Map Locations"
curl -X GET "$BASE_URL/api/v1/maps/locations/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Map Location Detail"
curl -X GET "$BASE_URL/api/v1/maps/locations/park/1/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Map Search"
curl -X GET "$BASE_URL/api/v1/maps/search/?q=disney"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Map Bounds Query"
curl -X GET "$BASE_URL/api/v1/maps/bounds/?north=40.7&south=40.6&east=-73.9&west=-74.0"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Map Statistics"
curl -X GET "$BASE_URL/api/v1/maps/stats/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Map Cache Status"
curl -X GET "$BASE_URL/api/v1/maps/cache/"
((ENDPOINT_NUM++))
fi
if should_run_endpoint true false; then
echo -e "\n$ENDPOINT_NUM. Invalidate Map Cache"
curl -X POST "$BASE_URL/api/v1/maps/cache/invalidate/" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"
((ENDPOINT_NUM++))
fi
# ============================================================================
# API DOCUMENTATION ENDPOINTS
# ============================================================================
if should_run_endpoint false true; then
echo -e "\n\n=== API DOCUMENTATION ENDPOINTS ==="
echo "$ENDPOINT_NUM. OpenAPI Schema"
curl -X GET "$BASE_URL/api/schema/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. Swagger UI"
curl -X GET "$BASE_URL/api/docs/"
((ENDPOINT_NUM++))
echo -e "\n$ENDPOINT_NUM. ReDoc"
curl -X GET "$BASE_URL/api/redoc/"
((ENDPOINT_NUM++))
fi
# ============================================================================
# HEALTH CHECK (Django Health Check)
# ============================================================================
if should_run_endpoint false false; then
echo -e "\n\n=== DJANGO HEALTH CHECK ==="
echo "$ENDPOINT_NUM. Django Health Check"
curl -X GET "$BASE_URL/health/"
((ENDPOINT_NUM++))
fi
echo -e "\n\n=== END OF API ENDPOINTS TEST SUITE ==="
echo "Total endpoints tested: $((ENDPOINT_NUM - 1))"
echo ""
echo "Notes:"
echo "- Replace YOUR_TOKEN_HERE with actual authentication tokens"
echo "- Replace /path/to/photo.jpg with actual file paths for photo uploads"
echo "- Replace numeric IDs (1, 2, etc.) with actual resource IDs"
echo "- Replace slug placeholders (park-slug, ride-slug) with actual slugs"
echo "- Adjust BASE_URL for your environment (localhost:8000, staging, production)"
echo ""
echo "Authentication required endpoints are marked with Authorization header"
echo "File upload endpoints use multipart/form-data (-F flag)"
echo "JSON endpoints use application/json content type"

95
apps/accounts/adapters.py Normal file
View File

@@ -0,0 +1,95 @@
from django.conf import settings
from django.http import HttpRequest
from typing import Optional, Any, Dict, Literal, TYPE_CHECKING, cast
from allauth.account.adapter import DefaultAccountAdapter # type: ignore[import]
from allauth.account.models import EmailConfirmation, EmailAddress # type: ignore[import]
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter # type: ignore[import]
from allauth.socialaccount.models import SocialLogin # type: ignore[import]
from django.contrib.auth import get_user_model
from django.contrib.sites.shortcuts import get_current_site
if TYPE_CHECKING:
from django.contrib.auth.models import AbstractUser
User = get_user_model()
class CustomAccountAdapter(DefaultAccountAdapter):
def is_open_for_signup(self, request: HttpRequest) -> Literal[True]:
"""
Whether to allow sign ups.
"""
return True
def get_email_confirmation_url(self, request: HttpRequest, emailconfirmation: EmailConfirmation) -> str:
"""
Constructs the email confirmation (activation) url.
"""
get_current_site(request)
# Ensure the key is treated as a string for the type checker
key = cast(str, getattr(emailconfirmation, "key", ""))
return f"{settings.LOGIN_REDIRECT_URL}verify-email?key={key}"
def send_confirmation_mail(self, request: HttpRequest, emailconfirmation: EmailConfirmation, signup: bool) -> None:
"""
Sends the confirmation email.
"""
current_site = get_current_site(request)
activate_url = self.get_email_confirmation_url(request, emailconfirmation)
# Cast key to str for typing consistency and template context
key = cast(str, getattr(emailconfirmation, "key", ""))
# Determine template early
if signup:
email_template = "account/email/email_confirmation_signup"
else:
email_template = "account/email/email_confirmation"
# Cast the possibly-unknown email_address to EmailAddress so the type checker knows its attributes
email_address = cast(EmailAddress, getattr(emailconfirmation, "email_address", None))
# Safely obtain email string (fallback to any top-level email on confirmation)
email_str = cast(str, getattr(email_address, "email", getattr(emailconfirmation, "email", "")))
# Safely obtain the user object, cast to the project's User model for typing
user_obj = cast("AbstractUser", getattr(email_address, "user", None))
# Explicitly type the context to avoid partial-unknown typing issues
ctx: Dict[str, Any] = {
"user": user_obj,
"activate_url": activate_url,
"current_site": current_site,
"key": key,
}
# Remove unnecessary cast; ctx is already Dict[str, Any]
self.send_mail(email_template, email_str, ctx) # type: ignore
class CustomSocialAccountAdapter(DefaultSocialAccountAdapter):
def is_open_for_signup(self, request: HttpRequest, sociallogin: SocialLogin) -> Literal[True]:
"""
Whether to allow social account sign ups.
"""
return True
def populate_user(
self, request: HttpRequest, sociallogin: SocialLogin, data: Dict[str, Any]
) -> "AbstractUser": # type: ignore[override]
"""
Hook that can be used to further populate the user instance.
"""
user = super().populate_user(request, sociallogin, data) # type: ignore
if getattr(sociallogin.account, "provider", None) == "discord": # type: ignore
user.discord_id = getattr(sociallogin.account, "uid", None) # type: ignore
return cast("AbstractUser", user) # Ensure return type is explicit
def save_user(
self, request: HttpRequest, sociallogin: SocialLogin, form: Optional[Any] = None
) -> "AbstractUser": # type: ignore[override]
"""
Save the newly signed up social login.
"""
user = super().save_user(request, sociallogin, form) # type: ignore
if user is None:
raise ValueError("User creation failed")
return cast("AbstractUser", user) # Ensure return type is explicit

View File

@@ -1,7 +1,10 @@
from typing import Any
from django.contrib import admin from django.contrib import admin
from django.contrib.auth.admin import UserAdmin from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
from django.utils.html import format_html from django.utils.html import format_html
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from django.http import HttpRequest
from django.db.models import QuerySet
from .models import ( from .models import (
User, User,
UserProfile, UserProfile,
@@ -12,7 +15,7 @@ from .models import (
) )
class UserProfileInline(admin.StackedInline): class UserProfileInline(admin.StackedInline[UserProfile, admin.options.AdminSite]):
model = UserProfile model = UserProfile
can_delete = False can_delete = False
verbose_name_plural = "Profile" verbose_name_plural = "Profile"
@@ -39,7 +42,7 @@ class UserProfileInline(admin.StackedInline):
) )
class TopListItemInline(admin.TabularInline): class TopListItemInline(admin.TabularInline[TopListItem]):
model = TopListItem model = TopListItem
extra = 1 extra = 1
fields = ("content_type", "object_id", "rank", "notes") fields = ("content_type", "object_id", "rank", "notes")
@@ -47,7 +50,7 @@ class TopListItemInline(admin.TabularInline):
@admin.register(User) @admin.register(User)
class CustomUserAdmin(UserAdmin): class CustomUserAdmin(DjangoUserAdmin[User]):
list_display = ( list_display = (
"username", "username",
"email", "email",
@@ -74,7 +77,7 @@ class CustomUserAdmin(UserAdmin):
"ban_users", "ban_users",
"unban_users", "unban_users",
] ]
inlines = [UserProfileInline] inlines: list[type[admin.StackedInline[UserProfile]]] = [UserProfileInline]
fieldsets = ( fieldsets = (
(None, {"fields": ("username", "password")}), (None, {"fields": ("username", "password")}),
@@ -126,75 +129,82 @@ class CustomUserAdmin(UserAdmin):
) )
@admin.display(description="Avatar") @admin.display(description="Avatar")
def get_avatar(self, obj): def get_avatar(self, obj: User) -> str:
if obj.profile.avatar: profile = getattr(obj, "profile", None)
if profile and getattr(profile, "avatar", None):
return format_html( return format_html(
'<img src="{}" width="30" height="30" style="border-radius:50%;" />', '<img src="{0}" width="30" height="30" style="border-radius:50%;" />',
obj.profile.avatar.url, getattr(profile.avatar, "url", ""), # type: ignore
) )
return format_html( return format_html(
'<div style="width:30px; height:30px; border-radius:50%; ' '<div style="width:30px; height:30px; border-radius:50%; '
"background-color:#007bff; color:white; display:flex; " "background-color:#007bff; color:white; display:flex; "
'align-items:center; justify-content:center;">{}</div>', 'align-items:center; justify-content:center;">{0}</div>',
obj.username[0].upper(), getattr(obj, "username", "?")[0].upper(), # type: ignore
) )
@admin.display(description="Status") @admin.display(description="Status")
def get_status(self, obj): def get_status(self, obj: User) -> str:
if obj.is_banned: if getattr(obj, "is_banned", False):
return format_html('<span style="color: red;">Banned</span>') return format_html('<span style="color: red;">{}</span>', "Banned")
if not obj.is_active: if not getattr(obj, "is_active", True):
return format_html('<span style="color: orange;">Inactive</span>') return format_html('<span style="color: orange;">{}</span>', "Inactive")
if obj.is_superuser: if getattr(obj, "is_superuser", False):
return format_html('<span style="color: purple;">Superuser</span>') return format_html('<span style="color: purple;">{}</span>', "Superuser")
if obj.is_staff: if getattr(obj, "is_staff", False):
return format_html('<span style="color: blue;">Staff</span>') return format_html('<span style="color: blue;">{}</span>', "Staff")
return format_html('<span style="color: green;">Active</span>') return format_html('<span style="color: green;">{}</span>', "Active")
@admin.display(description="Ride Credits") @admin.display(description="Ride Credits")
def get_credits(self, obj): def get_credits(self, obj: User) -> str:
try: try:
profile = obj.profile profile = getattr(obj, "profile", None)
if not profile:
return "-"
return format_html( return format_html(
"RC: {}<br>DR: {}<br>FR: {}<br>WR: {}", "RC: {0}<br>DR: {1}<br>FR: {2}<br>WR: {3}",
profile.coaster_credits, getattr(profile, "coaster_credits", 0),
profile.dark_ride_credits, getattr(profile, "dark_ride_credits", 0),
profile.flat_ride_credits, getattr(profile, "flat_ride_credits", 0),
profile.water_ride_credits, getattr(profile, "water_ride_credits", 0),
) )
except UserProfile.DoesNotExist: except UserProfile.DoesNotExist:
return "-" return "-"
@admin.action(description="Activate selected users") @admin.action(description="Activate selected users")
def activate_users(self, request, queryset): def activate_users(self, request: HttpRequest, queryset: QuerySet[User]) -> None:
queryset.update(is_active=True) queryset.update(is_active=True)
@admin.action(description="Deactivate selected users") @admin.action(description="Deactivate selected users")
def deactivate_users(self, request, queryset): def deactivate_users(self, request: HttpRequest, queryset: QuerySet[User]) -> None:
queryset.update(is_active=False) queryset.update(is_active=False)
@admin.action(description="Ban selected users") @admin.action(description="Ban selected users")
def ban_users(self, request, queryset): def ban_users(self, request: HttpRequest, queryset: QuerySet[User]) -> None:
from django.utils import timezone from django.utils import timezone
queryset.update(is_banned=True, ban_date=timezone.now()) queryset.update(is_banned=True, ban_date=timezone.now())
@admin.action(description="Unban selected users") @admin.action(description="Unban selected users")
def unban_users(self, request, queryset): def unban_users(self, request: HttpRequest, queryset: QuerySet[User]) -> None:
queryset.update(is_banned=False, ban_date=None, ban_reason="") queryset.update(is_banned=False, ban_date=None, ban_reason="")
def save_model(self, request, obj, form, change): def save_model(
self,
request: HttpRequest,
obj: User,
form: Any,
change: bool
) -> None:
creating = not obj.pk creating = not obj.pk
super().save_model(request, obj, form, change) super().save_model(request, obj, form, change)
if creating and obj.role != User.Roles.USER: if creating and getattr(obj, "role", "USER") != "USER":
# Ensure new user with role gets added to appropriate group group = Group.objects.filter(name=getattr(obj, "role", None)).first()
group = Group.objects.filter(name=obj.role).first()
if group: if group:
obj.groups.add(group) obj.groups.add(group) # type: ignore[attr-defined]
@admin.register(UserProfile) @admin.register(UserProfile)
class UserProfileAdmin(admin.ModelAdmin): class UserProfileAdmin(admin.ModelAdmin[UserProfile]):
list_display = ( list_display = (
"user", "user",
"display_name", "display_name",
@@ -235,7 +245,7 @@ class UserProfileAdmin(admin.ModelAdmin):
@admin.register(EmailVerification) @admin.register(EmailVerification)
class EmailVerificationAdmin(admin.ModelAdmin): class EmailVerificationAdmin(admin.ModelAdmin[EmailVerification]):
list_display = ("user", "created_at", "last_sent", "is_expired") list_display = ("user", "created_at", "last_sent", "is_expired")
list_filter = ("created_at", "last_sent") list_filter = ("created_at", "last_sent")
search_fields = ("user__username", "user__email", "token") search_fields = ("user__username", "user__email", "token")
@@ -247,21 +257,21 @@ class EmailVerificationAdmin(admin.ModelAdmin):
) )
@admin.display(description="Status") @admin.display(description="Status")
def is_expired(self, obj): def is_expired(self, obj: EmailVerification) -> str:
from django.utils import timezone from django.utils import timezone
from datetime import timedelta from datetime import timedelta
if timezone.now() - obj.last_sent > timedelta(days=1): if timezone.now() - getattr(obj, "last_sent", timezone.now()) > timedelta(days=1):
return format_html('<span style="color: red;">Expired</span>') return format_html('<span style="color: red;">{}</span>', "Expired")
return format_html('<span style="color: green;">Valid</span>') return format_html('<span style="color: green;">{}</span>', "Valid")
@admin.register(TopList) @admin.register(TopList)
class TopListAdmin(admin.ModelAdmin): class TopListAdmin(admin.ModelAdmin[TopList]):
list_display = ("title", "user", "category", "created_at", "updated_at") list_display = ("title", "user", "category", "created_at", "updated_at")
list_filter = ("category", "created_at", "updated_at") list_filter = ("category", "created_at", "updated_at")
search_fields = ("title", "user__username", "description") search_fields = ("title", "user__username", "description")
inlines = [TopListItemInline] inlines: list[type[admin.TabularInline[TopListItem]]] = [TopListItemInline]
fieldsets = ( fieldsets = (
( (
@@ -277,7 +287,7 @@ class TopListAdmin(admin.ModelAdmin):
@admin.register(TopListItem) @admin.register(TopListItem)
class TopListItemAdmin(admin.ModelAdmin): class TopListItemAdmin(admin.ModelAdmin[TopListItem]):
list_display = ("top_list", "content_type", "object_id", "rank") list_display = ("top_list", "content_type", "object_id", "rank")
list_filter = ("top_list__category", "rank") list_filter = ("top_list__category", "rank")
search_fields = ("top_list__title", "notes") search_fields = ("top_list__title", "notes")
@@ -290,7 +300,7 @@ class TopListItemAdmin(admin.ModelAdmin):
@admin.register(PasswordReset) @admin.register(PasswordReset)
class PasswordResetAdmin(admin.ModelAdmin): class PasswordResetAdmin(admin.ModelAdmin[PasswordReset]):
"""Admin interface for password reset tokens""" """Admin interface for password reset tokens"""
list_display = ( list_display = (
@@ -341,20 +351,19 @@ class PasswordResetAdmin(admin.ModelAdmin):
) )
@admin.display(description="Status", boolean=True) @admin.display(description="Status", boolean=True)
def is_expired(self, obj): def is_expired(self, obj: PasswordReset) -> str:
"""Display expiration status with color coding"""
from django.utils import timezone from django.utils import timezone
if obj.used: if getattr(obj, "used", False):
return format_html('<span style="color: blue;">Used</span>') return format_html('<span style="color: blue;">{}</span>', "Used")
elif timezone.now() > obj.expires_at: elif timezone.now() > getattr(obj, "expires_at", timezone.now()):
return format_html('<span style="color: red;">Expired</span>') return format_html('<span style="color: red;">{}</span>', "Expired")
return format_html('<span style="color: green;">Valid</span>') return format_html('<span style="color: green;">{}</span>', "Valid")
def has_add_permission(self, request): def has_add_permission(self, request: HttpRequest) -> bool:
"""Disable manual creation of password reset tokens""" """Disable manual creation of password reset tokens"""
return False return False
def has_change_permission(self, request, obj=None): def has_change_permission(self, request: HttpRequest, obj: Any = None) -> bool:
"""Allow viewing but restrict editing of password reset tokens""" """Allow viewing but restrict editing of password reset tokens"""
return getattr(request.user, "is_superuser", False) return getattr(request.user, "is_superuser", False)

View File

@@ -15,17 +15,17 @@ class Command(BaseCommand):
create_default_groups() create_default_groups()
# Sync existing users with groups based on their roles # Sync existing users with groups based on their roles
users = User.objects.exclude(role=User.Roles.USER) users = User.objects.exclude(role="USER")
for user in users: for user in users:
group = Group.objects.filter(name=user.role).first() group = Group.objects.filter(name=user.role).first()
if group: if group:
user.groups.add(group) user.groups.add(group)
# Update staff/superuser status based on role # Update staff/superuser status based on role
if user.role == User.Roles.SUPERUSER: if user.role == "SUPERUSER":
user.is_superuser = True user.is_superuser = True
user.is_staff = True user.is_staff = True
elif user.role in [User.Roles.ADMIN, User.Roles.MODERATOR]: elif user.role in ["ADMIN", "MODERATOR"]:
user.is_staff = True user.is_staff = True
user.save() user.save()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,76 @@
# Generated by Django 5.2.6 on 2025-09-21 01:29
import django.db.models.deletion
import pgtrigger.compiler
import pgtrigger.migrations
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("accounts", "0001_initial"),
]
operations = [
pgtrigger.migrations.RemoveTrigger(
model_name="userprofile",
name="insert_insert",
),
pgtrigger.migrations.RemoveTrigger(
model_name="userprofile",
name="update_update",
),
migrations.AddField(
model_name="userprofile",
name="avatar",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="django_cloudflareimages_toolkit.cloudflareimage",
),
),
migrations.AddField(
model_name="userprofileevent",
name="avatar",
field=models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
related_query_name="+",
to="django_cloudflareimages_toolkit.cloudflareimage",
),
),
pgtrigger.migrations.AddTrigger(
model_name="userprofile",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "accounts_userprofileevent" ("avatar_id", "bio", "coaster_credits", "dark_ride_credits", "discord", "display_name", "flat_ride_credits", "id", "instagram", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "profile_id", "pronouns", "twitter", "user_id", "water_ride_credits", "youtube") VALUES (NEW."avatar_id", NEW."bio", NEW."coaster_credits", NEW."dark_ride_credits", NEW."discord", NEW."display_name", NEW."flat_ride_credits", NEW."id", NEW."instagram", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."profile_id", NEW."pronouns", NEW."twitter", NEW."user_id", NEW."water_ride_credits", NEW."youtube"); RETURN NULL;',
hash="a7ecdb1ac2821dea1fef4ec917eeaf6b8e4f09c8",
operation="INSERT",
pgid="pgtrigger_insert_insert_c09d7",
table="accounts_userprofile",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="userprofile",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "accounts_userprofileevent" ("avatar_id", "bio", "coaster_credits", "dark_ride_credits", "discord", "display_name", "flat_ride_credits", "id", "instagram", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "profile_id", "pronouns", "twitter", "user_id", "water_ride_credits", "youtube") VALUES (NEW."avatar_id", NEW."bio", NEW."coaster_credits", NEW."dark_ride_credits", NEW."discord", NEW."display_name", NEW."flat_ride_credits", NEW."id", NEW."instagram", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."profile_id", NEW."pronouns", NEW."twitter", NEW."user_id", NEW."water_ride_credits", NEW."youtube"); RETURN NULL;',
hash="81607e492ffea2a4c741452b860ee660374cc01d",
operation="UPDATE",
pgid="pgtrigger_update_update_87ef6",
table="accounts_userprofile",
when="AFTER",
),
),
),
]

View File

@@ -121,10 +121,6 @@ class User(AbstractUser):
"""Get the user's display name, falling back to username if not set""" """Get the user's display name, falling back to username if not set"""
if self.display_name: if self.display_name:
return self.display_name return self.display_name
# Fallback to profile display_name for backward compatibility
profile = getattr(self, "profile", None)
if profile and profile.display_name:
return profile.display_name
return self.username return self.username
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
@@ -635,4 +631,6 @@ class NotificationPreference(TrackedModel):
def create_notification_preference(sender, instance, created, **kwargs): def create_notification_preference(sender, instance, created, **kwargs):
"""Create notification preferences when a new user is created.""" """Create notification preferences when a new user is created."""
if created: if created:
NotificationPreference.objects.create(user=instance) NotificationPreference.objects.get_or_create(user=instance)
# Signal moved to signals.py to avoid duplication

View File

@@ -31,7 +31,7 @@ class UserDeletionService:
"is_active": False, "is_active": False,
"is_staff": False, "is_staff": False,
"is_superuser": False, "is_superuser": False,
"role": User.Roles.USER, "role": "USER",
"is_banned": True, "is_banned": True,
"ban_reason": "System placeholder for deleted users", "ban_reason": "System placeholder for deleted users",
"ban_date": timezone.now(), "ban_date": timezone.now(),
@@ -178,7 +178,7 @@ class UserDeletionService:
return False, "Superuser accounts cannot be deleted for security reasons. Please contact system administrator or remove superuser privileges first." return False, "Superuser accounts cannot be deleted for security reasons. Please contact system administrator or remove superuser privileges first."
# Check if user has critical admin role # Check if user has critical admin role
if user.role == User.Roles.ADMIN and user.is_staff: if user.role == "ADMIN" and user.is_staff:
return False, "Admin accounts with staff privileges cannot be deleted. Please remove admin privileges first or contact system administrator." return False, "Admin accounts with staff privileges cannot be deleted. Please remove admin privileges first or contact system administrator."
# Add any other business rules here # Add any other business rules here

View File

@@ -10,59 +10,41 @@ from .models import User, UserProfile
@receiver(post_save, sender=User) @receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs): def create_user_profile(sender, instance, created, **kwargs):
"""Create UserProfile for new users""" """Create UserProfile for new users - unified signal handler"""
try: if created:
if created:
# Create profile
profile = UserProfile.objects.create(user=instance)
# If user has a social account with avatar, download it
social_account = instance.socialaccount_set.first()
if social_account:
extra_data = social_account.extra_data
avatar_url = None
if social_account.provider == "google":
avatar_url = extra_data.get("picture")
elif social_account.provider == "discord":
avatar = extra_data.get("avatar")
discord_id = extra_data.get("id")
if avatar:
avatar_url = f"https://cdn.discordapp.com/avatars/{discord_id}/{avatar}.png"
if avatar_url:
try:
response = requests.get(avatar_url, timeout=60)
if response.status_code == 200:
img_temp = NamedTemporaryFile(delete=True)
img_temp.write(response.content)
img_temp.flush()
file_name = f"avatar_{instance.username}.png"
profile.avatar.save(file_name, File(img_temp), save=True)
except Exception as e:
print(
f"Error downloading avatar for user {instance.username}: {
str(e)
}"
)
except Exception as e:
print(f"Error creating profile for user {instance.username}: {str(e)}")
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
"""Ensure UserProfile exists and is saved"""
try:
# Try to get existing profile first
try: try:
profile = instance.profile # Use get_or_create to prevent duplicates
profile.save() profile, profile_created = UserProfile.objects.get_or_create(user=instance)
except UserProfile.DoesNotExist:
# Profile doesn't exist, create it if profile_created:
UserProfile.objects.create(user=instance) # If user has a social account with avatar, download it
except Exception as e: try:
print(f"Error saving profile for user {instance.username}: {str(e)}") social_account = instance.socialaccount_set.first()
if social_account:
extra_data = social_account.extra_data
avatar_url = None
if social_account.provider == "google":
avatar_url = extra_data.get("picture")
elif social_account.provider == "discord":
avatar = extra_data.get("avatar")
discord_id = extra_data.get("id")
if avatar:
avatar_url = f"https://cdn.discordapp.com/avatars/{discord_id}/{avatar}.png"
if avatar_url:
response = requests.get(avatar_url, timeout=60)
if response.status_code == 200:
img_temp = NamedTemporaryFile(delete=True)
img_temp.write(response.content)
img_temp.flush()
file_name = f"avatar_{instance.username}.png"
profile.avatar.save(file_name, File(img_temp), save=True)
except Exception as e:
print(f"Error downloading avatar for user {instance.username}: {str(e)}")
except Exception as e:
print(f"Error creating profile for user {instance.username}: {str(e)}")
@receiver(pre_save, sender=User) @receiver(pre_save, sender=User)
@@ -75,43 +57,43 @@ def sync_user_role_with_groups(sender, instance, **kwargs):
# Role has changed, update groups # Role has changed, update groups
with transaction.atomic(): with transaction.atomic():
# Remove from old role group if exists # Remove from old role group if exists
if old_instance.role != User.Roles.USER: if old_instance.role != "USER":
old_group = Group.objects.filter(name=old_instance.role).first() old_group = Group.objects.filter(name=old_instance.role).first()
if old_group: if old_group:
instance.groups.remove(old_group) instance.groups.remove(old_group)
# Add to new role group # Add to new role group
if instance.role != User.Roles.USER: if instance.role != "USER":
new_group, _ = Group.objects.get_or_create(name=instance.role) new_group, _ = Group.objects.get_or_create(name=instance.role)
instance.groups.add(new_group) instance.groups.add(new_group)
# Special handling for superuser role # Special handling for superuser role
if instance.role == User.Roles.SUPERUSER: if instance.role == "SUPERUSER":
instance.is_superuser = True instance.is_superuser = True
instance.is_staff = True instance.is_staff = True
elif old_instance.role == User.Roles.SUPERUSER: elif old_instance.role == "SUPERUSER":
# If removing superuser role, remove superuser # If removing superuser role, remove superuser
# status # status
instance.is_superuser = False instance.is_superuser = False
if instance.role not in [ if instance.role not in [
User.Roles.ADMIN, "ADMIN",
User.Roles.MODERATOR, "MODERATOR",
]: ]:
instance.is_staff = False instance.is_staff = False
# Handle staff status for admin and moderator roles # Handle staff status for admin and moderator roles
if instance.role in [ if instance.role in [
User.Roles.ADMIN, "ADMIN",
User.Roles.MODERATOR, "MODERATOR",
]: ]:
instance.is_staff = True instance.is_staff = True
elif old_instance.role in [ elif old_instance.role in [
User.Roles.ADMIN, "ADMIN",
User.Roles.MODERATOR, "MODERATOR",
]: ]:
# If removing admin/moderator role, remove staff # If removing admin/moderator role, remove staff
# status # status
if instance.role not in [User.Roles.SUPERUSER]: if instance.role not in ["SUPERUSER"]:
instance.is_staff = False instance.is_staff = False
except User.DoesNotExist: except User.DoesNotExist:
pass pass
@@ -130,7 +112,7 @@ def create_default_groups():
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
# Create Moderator group # Create Moderator group
moderator_group, _ = Group.objects.get_or_create(name=User.Roles.MODERATOR) moderator_group, _ = Group.objects.get_or_create(name="MODERATOR")
moderator_permissions = [ moderator_permissions = [
# Review moderation permissions # Review moderation permissions
"change_review", "change_review",
@@ -149,7 +131,7 @@ def create_default_groups():
] ]
# Create Admin group # Create Admin group
admin_group, _ = Group.objects.get_or_create(name=User.Roles.ADMIN) admin_group, _ = Group.objects.get_or_create(name="ADMIN")
admin_permissions = moderator_permissions + [ admin_permissions = moderator_permissions + [
# User management permissions # User management permissions
"change_user", "change_user",

View File

@@ -109,7 +109,7 @@ class SignalsTestCase(TestCase):
create_default_groups() create_default_groups()
moderator_group = Group.objects.get(name=User.Roles.MODERATOR) moderator_group = Group.objects.get(name="MODERATOR")
self.assertIsNotNone(moderator_group) self.assertIsNotNone(moderator_group)
self.assertTrue( self.assertTrue(
moderator_group.permissions.filter(codename="change_review").exists() moderator_group.permissions.filter(codename="change_review").exists()
@@ -118,7 +118,7 @@ class SignalsTestCase(TestCase):
moderator_group.permissions.filter(codename="change_user").exists() moderator_group.permissions.filter(codename="change_user").exists()
) )
admin_group = Group.objects.get(name=User.Roles.ADMIN) admin_group = Group.objects.get(name="ADMIN")
self.assertIsNotNone(admin_group) self.assertIsNotNone(admin_group)
self.assertTrue( self.assertTrue(
admin_group.permissions.filter(codename="change_review").exists() admin_group.permissions.filter(codename="change_review").exists()

View File

@@ -42,7 +42,7 @@ class UserDeletionServiceTest(TestCase):
self.assertEqual(deleted_user.email, "deleted@thrillwiki.com") self.assertEqual(deleted_user.email, "deleted@thrillwiki.com")
self.assertFalse(deleted_user.is_active) self.assertFalse(deleted_user.is_active)
self.assertTrue(deleted_user.is_banned) self.assertTrue(deleted_user.is_banned)
self.assertEqual(deleted_user.role, User.Roles.USER) self.assertEqual(deleted_user.role, "USER")
# Check profile was created # Check profile was created
self.assertTrue(hasattr(deleted_user, "profile")) self.assertTrue(hasattr(deleted_user, "profile"))

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More