Files
Reklamator/specs/002-product-list/spec.md
T
gurixandClaude 0f71ba969f Add implementation plan for product selection landing page (Feature 002)
Completed planning phases 0 and 1 for simple landing page feature.

## Plan Overview:

**Approach**: Minimal addition to existing Flask app - reuse Product model,
add one route, one template. No new dependencies or complexity.

**Constitution Check**:  All 5 principles satisfied
- Specification-first development (spec.md complete)
- Test-first discipline (TDD workflow defined)
- Independent user stories (3 stories, all independently testable)
- Simplicity (reuses existing Flask/Jinja2/Product architecture)
- Documentation as code (all artifacts in specs/002-product-list/)

## Artifacts Created:

### Phase 0: Research (research.md)
- Reuses infrastructure from feature 001 (Flask, Jinja2, file storage)
- Single new decision: Product.load_active() method for filtering/sorting
- Performance analysis: <100ms for 100 products (well under 1s target)

### Phase 1: Design & Contracts
- **data-model.md**: Documents Product model extension (load_active method)
- **contracts/landing-page.yaml**: OpenAPI contract for GET / route
- **quickstart.md**: Developer implementation guide with:
  - Step-by-step implementation checklist
  - Code snippets for route, template, tests
  - TDD workflow (write tests → verify fail → implement → pass)
  - Manual verification checklist

### Agent Context
- Updated CLAUDE.md with feature technologies (no new tech added)

## Implementation Summary:

**New Files** (to be created):
- app/routes/landing.py - Landing page route handler
- app/templates/landing/index.html - Product list template
- tests/contract/test_landing_routes.py - Contract tests (6 scenarios)
- tests/integration/test_landing_flow.py - User journey test

**Modified Files**:
- app/models/product.py - Add load_active() class method
- app/__init__.py - Register landing blueprint

## Key Technical Decisions:

1. **Filtering**: status=='active' AND submission_url_slug exists
2. **Sorting**: Alphabetical by name (case-insensitive), then product_id
3. **Empty State**: "No products are currently accepting feedback" message
4. **XSS Prevention**: Jinja2 auto-escaping (no manual escaping needed)
5. **Performance**: File I/O sufficient (<1s for 100 products, no caching)

## Next Steps:

1. Run /speckit.tasks to generate tasks.md
2. Run /speckit.implement to execute TDD workflow
3. Verify all tests pass
4. Manual verification checklist
5. Create pull request

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 14:26:47 +02:00

9.8 KiB

Feature Specification: Product Selection Landing Page

Feature Branch: 002-product-list Created: 2025-10-17 Status: Draft Input: User description: "At the moment visitors of the website need to know the link to the product submission page when they want to submit a feedback. The now should be able to see a list of all active products in order to choose what product they want to give a feedback."

Clarifications

Session 2025-10-17

  • Q: When a product configuration has a missing or invalid submission_url_slug, how should the landing page handle it? → A: Skip the product silently and log an error (user sees only valid products)
  • Q: How should archived products be handled on the landing page? → A: Do not display archived products at all (only show active products)
  • Q: When an authenticated product owner or admin accesses the landing page at /, what should happen? → A: Show the landing page normally (authentication doesn't affect access)
  • Q: When a product has no description field (or it's empty), what should be displayed? → A: Display product name only (no description text shown)
  • Q: When multiple products have identical names, how should they be sorted in the alphabetical list? → A: Order by product_id alphabetically as secondary sort

User Scenarios & Testing (mandatory)

User Story 1 - Browse and Select Product (Priority: P1)

A visitor arrives at the Reklamator platform without knowing the specific product URL. They want to discover which products accept feedback and navigate to the appropriate submission form for the product they're interested in.

Why this priority: This is the core functionality that enables product discoverability. Without this, the system requires users to have prior knowledge of product URLs, creating a significant barrier to feedback submission. This directly addresses the user's stated problem.

Independent Test: Can be fully tested by visiting the root landing page, seeing a list of active products with their names and descriptions, clicking on a product, and being redirected to that product's submission form. Delivers immediate value by making the feedback system discoverable.

Acceptance Scenarios:

  1. Given a visitor arrives at the platform root URL (/), When they view the page, Then they see a list of all active products with product names (and descriptions if available)
  2. Given multiple active products exist in the system, When a visitor views the landing page, Then all active products are displayed in a clear, organized list
  3. Given a visitor sees the product list, When they click on a product name or "Submit Feedback" button, Then they are redirected to that product's submission form (/submit/{product-slug})
  4. Given a product has a descriptive summary, When displayed on the landing page, Then the summary helps the visitor understand what the product is
  5. Given a visitor is on the landing page, When they review the products, Then they can easily distinguish between different products

User Story 2 - See Product Availability Status (Priority: P2)

A visitor wants to understand which products are currently accepting feedback and which might be archived or inactive, so they don't waste time trying to submit feedback to a product that's no longer active.

Why this priority: Provides transparency about product status and prevents user frustration. This is secondary to basic discovery but improves user experience by setting clear expectations.

Independent Test: Can be tested independently by creating products with different statuses (active, archived) and verifying that only active products appear on the landing page (archived products are not displayed).

Acceptance Scenarios:

  1. Given a product has status "active", When the landing page loads, Then the product appears in the list
  2. Given a product has status "archived", When the landing page loads, Then the product does NOT appear in the list
  3. Given some products are active and some are archived, When the landing page loads, Then only active products are shown
  4. Given a visitor views the landing page, When they see a product listed, Then they can trust that clicking it will allow them to submit feedback

User Story 3 - Direct Navigation with Known Product (Priority: P3)

A visitor who already knows which product they want to submit feedback for can quickly find it in the list or use existing direct URL functionality without interference.

Why this priority: Ensures backwards compatibility and doesn't disrupt existing user workflows. Users with bookmarked URLs or shared links should continue to work seamlessly.

Independent Test: Can be tested by directly navigating to /submit/{product-slug} and verifying it still works, or by using a search/filter on the landing page to quickly locate a known product.

Acceptance Scenarios:

  1. Given a visitor has a direct link to /submit/product-name, When they visit that URL, Then they go directly to the submission form (existing behavior preserved)
  2. Given a visitor knows the product name, When they view the landing page, Then they can quickly identify their product in the list
  3. Given many products exist (10+), When a visitor has a specific product in mind, Then they can find it efficiently (via alphabetical sorting or search if implemented)

Edge Cases

  • What happens when there are no active products? Display a message: "No products are currently accepting feedback. Please check back later."
  • What happens when all products are archived? Same as no active products - display the "No products are currently accepting feedback" message (archived products are not shown)
  • What happens when a product has no description? Display product name only (no description text or placeholder shown)
  • What happens when a visitor accesses the landing page while authenticated as a product owner? They see the landing page normally (authentication doesn't affect landing page access)
  • What happens when product names are very long or contain special characters? Ensure proper text truncation/wrapping and HTML escaping for XSS prevention
  • What happens when multiple products have identical names? Display them all; sort by product_id alphabetically as secondary sort (after name)
  • What happens if a product's submission_url_slug is missing or invalid? Skip that product silently in the listing and log an error for admin investigation

Requirements (mandatory)

Functional Requirements

  • FR-001: System MUST display a landing page at the root URL (/) showing all active products available for feedback submission
  • FR-002: System MUST retrieve product list from the file-based storage (data/products/*/config.yaml)
  • FR-003: System MUST filter products to show ONLY those with status: active in their config.yaml
  • FR-004: System MUST display for each product: product name (name field from config.yaml)
  • FR-005: System MUST provide a clickable link/button for each product that navigates to /submit/{submission_url_slug}
  • FR-006: System MUST handle products without descriptions gracefully (show product name only, no placeholder text)
  • FR-007: System MUST maintain existing direct URL functionality (/submit/{product-slug} continues to work)
  • FR-008: Landing page MUST be accessible to anonymous users (no authentication required); authenticated users also see the landing page normally
  • FR-009: System MUST sort products alphabetically by name (case-insensitive); if names are identical, use product_id alphabetically as secondary sort
  • FR-010: System MUST handle the case where no active products exist (display appropriate message)
  • FR-011: Product listing MUST be server-side rendered (consistent with project's no-JavaScript requirement)
  • FR-012: System MUST escape all product names and descriptions to prevent XSS attacks
  • FR-013: Landing page MUST use the same minimal HTML/CSS styling as the rest of the application (no frameworks)
  • FR-014: System MUST log when the landing page is accessed (for monitoring/analytics)
  • FR-015: System MUST skip products with missing or invalid submission_url_slug and log an error (product not shown to users)

Key Entities

  • Product: Existing entity from 001-build-an-application. Key attributes relevant to this feature:

    • product_id: Unique identifier
    • name: Display name for the product
    • submission_url_slug: URL segment for submission form
    • status: "active" or "archived" - determines visibility on landing page
    • description (optional): Brief description to help users identify the product
  • Landing Page View: New view/route that aggregates active products and presents them to visitors

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: Visitors can discover and access any active product's feedback submission form in 2 clicks or less (landing page → product selection → submission form)
  • SC-002: Landing page loads with product list in under 1 second for up to 100 active products
  • SC-003: 100% of active products in the system appear on the landing page within 5 seconds of being marked active
  • SC-004: Zero direct URL submissions are broken by this feature (backwards compatibility maintained)
  • SC-005: Landing page displays appropriate message when zero active products exist (no blank page or error)
  • SC-006: Product names and descriptions are properly escaped (no XSS vulnerability when product names contain HTML/script tags)
  • SC-007: Landing page renders correctly without JavaScript (consistent with application architecture)
  • SC-008: Users can visually distinguish between products when 5+ products are listed (clear visual separation)