Implement product selection landing page (Feature 002)

Adds landing page at root URL (/) that displays all active products with links to feedback submission forms. This replaces the requirement for users to know direct product URLs.

Changes:
- Added Product.load_active() method to filter and sort active products alphabetically
- Created landing route blueprint with error handling and structured logging
- Registered landing blueprint in app factory, replacing old index route
- Created landing page template with product list and empty state
- Added comprehensive contract tests (6 tests) covering active products, filtering, sorting, XSS prevention
- Added integration test for complete user flow from landing page to submission form

All 7 tests pass. User Story 1 (P1 - MVP) complete.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-17 14:54:51 +02:00
co-authored by Claude
parent 8640d803a6
commit f7f225ad09
7 changed files with 331 additions and 32 deletions
+16
View File
@@ -159,6 +159,22 @@ class Product:
return products
@classmethod
def load_active(cls):
"""Load all active products, sorted alphabetically by name then product_id
Returns:
list[Product]: Active products with valid submission_url_slug, sorted by:
1. name (case-insensitive alphabetical)
2. product_id (alphabetical) as tiebreaker
Products with missing/invalid submission_url_slug are excluded.
"""
all_products = cls.get_all()
active = [p for p in all_products
if p.status == 'active' and p.submission_url_slug]
return sorted(active, key=lambda p: (p.name.lower(), p.product_id))
def save(self):
"""Save product to filesystem"""
product_dir = self._get_product_dir(self.product_id)