feat: Add blog, media, and support apps, implement ride credits and image API, and remove toplist feature.

This commit is contained in:
pacnpal
2025-12-26 15:15:28 -05:00
parent cd8868a591
commit 00699d53b4
77 changed files with 7274 additions and 538 deletions

View File

@@ -2,67 +2,112 @@
## User Review Required
> [!IMPORTANT]
> **Measurement Unit System**: The backend will store all values in **Metric**. The Frontend (Nuxt Composables) will handle conversion to Imperial based on user preference.
> **Moderation Workflow**: A State Machine (Pending -> Claimed -> Approved) will be enforced for all user submissions.
> **Measurement Unit System**: The backend will store all values in **Metric**. The Frontend (`useUnits` composable) will handle conversion to Imperial based on user preference.
> **Sacred Pipeline Enforcement**: All user edits create `Submission` records (stored as JSON). No direct database edits are allowed for non-admin users.
## Proposed Changes
### Backend (Django + DRF)
#### App Structure & Models
- [x] **`apps/core`**: Base models (`SluggedModel`, `TimeStampedModel`), History (`pghistory`, `SlugHistory`), Utilities.
- [x] **`apps/accounts`**: `User`, `UserProfile` (bio, location, visual prefs), `Auth` (MFA, Magic Link).
- [x] **`apps/parks`**: `Park` (name, location, dates, status, owner/operator FKs).
- [x] **`apps/rides`**:
- `Ride` (name, park FK, model FK, specs: height/speed/etc stored in metric).
- `Manufacturer`, `Designer`, `RideModel` (Company models).
- `RideCredit` (M2M: User <-> Ride). **Attributes**: `count`, `first_ridden_at`, `notes`, `ranking`.
- [ ] **`apps/reviews`**: `Review` (User, Entity GenericFK, rating 1-5, text, helpful votes).
- [ ] **`apps/media`**: `Photo` (image, user, caption, entity GenericFK), `Video`.
- [x] **`apps/lists`**: `UserList` (Custom rankings/lists).
- [x] **`apps/moderation`**: `Submission` (User, ContentType, Object ID, Changes JSON, Status: Pending/Claimed/Approved/Rejected, Moderator FK), `Report`.
- [ ] **`apps/blog`**: `Post`, `Tag`.
- [ ] **`apps/support`**: `Ticket` (Contact form).
#### 1. Core & Auth Infrastructure
- [x] **`apps.core`**: Implement `TrackedModel` using `pghistory` for all core entities to support Edit History and Versioning (Section 15).
- [x] **`apps.accounts`**:
- `User` & `UserProfile` models (Bio, Location, Home Park).
- **Settings Support**: Endpoints for changing Email, Password, MFA, and Sessions (Section 9.1-9.2).
- **Privacy**: Fields for `public_profile`, `show_location`, etc. (Section 9.3).
- **Data Export**: Endpoint to generate JSON dump of all user data (Section 9.6).
- **Account Deletion**: `UserDeletionRequest` model with 7-day grace period (Section 9.6).
#### API & Logic
- **DRF ViewSets**: Full CRUD for all entities (read-only for public, authenticated for mutations).
- **Moderation Middleware/Signals**: Intercept mutations to create `Submission` records instead of direct saves for non-staff.
- **Versioning**: `pghistory` and `SlugHistory` are already partially implemented in `core`.
- **Search**: Global search endpoint.
- **Geolocation**: `PostGIS` integrations (already partially in `parks.location_utils`).
#### 2. Entity Models & Logic ("Live" Data)
- [x] **`apps.parks`**: `Park` (with Operator/Owner FKs, Geolocation).
- [x] **`apps.rides`**: `Ride` (Status FSM), `RideModel`, `Manufacturer`, `Designer`.
- [x] **`apps.rides` (Credits)**: `RideCredit` Through-Model with `count`, `rating`, `date`, `notes`. Constraint: Unique(user, ride).
- [x] **`apps.companies`**: `Company` model with types (`Manufacturer`, `Designer`, `Operator`, `Owner`).
- [x] **`apps.lists`**: `UserList` (Ranking System) and `UserListItem`.
- [x] **`apps.reviews`**: `Review` model (GenericFK) with Aggregation Logic.
#### 3. The Sacred Pipeline (`apps.moderation`)
- [x] **Submission Model**: Stores `changes` (JSON), `status` (State Machine), `moderator_note`.
- [x] **Submission Serializers**: Handle validation of "Proposed Data" vs "Live Data".
- [x] **Queue Endpoints**: `list_pending`, `claim`, `approve`, `reject`, `activity_log`, `stats`.
- [x] **Reports**: `Report` model and endpoints.
### Frontend (Nuxt 4)
#### Architecture
- **Directory Structure**:
- `app/pages/`: File-based routing (e.g., `parks/[slug].vue`).
- `app/components/`: Reusable UI components (Design System).
- `app/composables/`: Logic reuse (`useUnits`, `useAuth`, `useApi`).
- `app/stores/`: Pinia stores (`userStore`, `toastStore`).
- `app/layouts/`: `default.vue`, `auth.vue`.
- **Tech Stack**: Nuxt 4, Nuxt UI (Tailwind based), Pinia, VueUse.
#### 1. Initial Setup & Core
- [x] **Composables**: `useUnits` (Metric/Imperial), `useAuth` (MFA, Session), `useApi`.
- [x] **Layouts**: Standard Layout (Hero, Tabs), Auth Layout.
#### Key Features & Composables
- **`useUnits`**: Reactively converts metric props to imperial if user pref is set.
- **`useAuth`**: Handles JWT/Session, MFA state, User fetching.
- **`useModeration`**: For moderators to claim/approve actions.
- **Forms**: `Zod` schema validation matching DRF serializers.
#### 2. Discovery & Search (Section 1 & 6)
- [x] **Global Search**: Hero Search with Autocomplete (Parks, Rides, Companies).
- [x] **Discovery Tabs** (11 Sections):
- [x] Trending Parks / Rides
- [x] New Parks / Rides
- [x] Top Parks / Rides
- [x] Opening Soon / Recently Opened
- [x] Closing Soon / Recently Closed
- [x] Recent Changes Feed
#### Design System
- **Theme**: Dark/Light mode support (built-in to Nuxt UI).
- **Components**:
- `EntityCard` (Park/Ride summary).
- `StandardLayout` (Hero, Tabs, Content).
- `MediaGallery`.
- `ReviewList`.
#### 3. Content Pages (Read-Only Views)
- [ ] **Park Detail**: Tabs (Overview, Rides, Reviews, Photos, History).
- [ ] **Ride Detail**: Tabs (Overview, Specifications, Reviews, Photos, History).
- [ ] **Company Pages**: Manufacturer, Designer, Operator, Property Owner details.
- [ ] **Maps**: Interactive "Parks Nearby" map.
#### 4. The Sacred Submission Pipeline (Write Views)
- [ ] **Submission Forms** (Multi-step Wizards):
- [ ] **Park Form**: Location, Dates, Media, Relations.
- [ ] **Ride Form**: Specs (with Unit Toggle), Relations, Park selection.
- [ ] **Company Form**: Type selection, HQ, details.
- [ ] **Photo Upload**: Bulk upload, captioning, crop.
- [ ] **Editing**: Load existing data into form -> Submit as JSON Diff.
#### 5. Moderation Interface (Section 16)
- [ ] **Dashboard**: Queue stats, Assignments.
- [ ] **Queues**:
- [ ] **Pending Queue**: Filter by Type, Submitter, Date.
- [ ] **Reports Queue**.
- [ ] **Audit Log**.
- [ ] **Review Workspace**:
- [ ] **Diff Viewer**: Visual Old vs New comparison.
- [ ] **Actions**: Claim, Approve, Reject (with reason), Edit.
#### 6. User Experience & Settings
- [ ] **User Profile**: Activity Feed, Credits Tab, Lists Tab, Reviews Tab.
- [ ] **Ride Credits Management**: Add/Edit Credit (Date, Count, Notes).
- [ ] **Settings Area** (6 Tabs):
- [ ] Account & Profile (Edit generic info).
- [ ] Security (MFA setup, Active Sessions).
- [ ] Privacy (Visibility settings).
- [ ] Notifications.
- [ ] Location & Info (Timezone, Home Park).
- [ ] Data & Export (JSON Download, Delete Account).
#### 7. Lists System
- [ ] **List Management**: Create/Edit Lists (Public/Private).
- [ ] **List Editor**: Search items, Add to list, Drag-and-drop reorder, Add notes.
## Verification Plan
### Automated Tests
- **Backend**: `pytest` for Model constraints, API endpoints, and Moderation flow.
- **Frontend**: `vitest` for Unit/Composable tests. E2E tests for critical flows (Submission -> Moderation -> Publish).
- **Backend**: `pytest` for all Model constraints and API permissions.
- Test Submission State Machine: `Pending -> Claimed -> Approved`.
- Test Versioning: Ensure `pghistory` tracks changes on approval.
- **Frontend**: `vitest` for Unit Tests (Composables).
### Manual Verification
1. **Ride Credits**: User adds a ride, verifies count increments.
2. **Moderation**: User submits data -> Mod claims -> Mod approves -> Public data updates.
3. **Units**: Toggle preference, verify stats update (e.g., km/h -> mph).
### Manual Verification Flows
1. **Sacred Pipeline Flow**:
- **User**: Submit a change to "Top Thrill 2" (add stats).
- **Moderator**: Go to Queue -> Claim -> Verify Diff -> Approve.
- **Public**: Verify "Top Thrill 2" page shows new stats and "Last Updated" is now.
- **History**: Verify "History" tab shows the update event.
2. **Ride Credits**:
- Go to "Iron Gwazi" page.
- Click "Add to Credits" -> Enter `Count: 5`, `Rating: 4.5`.
- Go to Profile -> Ride Credits. Verify Iron Gwazi is listed with correct data.
3. **Data Privacy & Export**:
- Go to Settings -> Privacy -> Toggle "Private Profile".
- Open Profile URL in Incognito -> Verify 404 or "Private" message.
- Go to Settings -> Data -> "Download Data" -> Verify JSON structure.