bulk commit changes!

This commit is contained in:
2026-02-13 02:32:06 -05:00
parent c8f98c54c9
commit bf4a40f533
152 changed files with 2210 additions and 19 deletions

View File

@@ -0,0 +1,59 @@
## ADDED Requirements
### Requirement: Configurable provider priority
The system SHALL support configuring image provider order via `ROYALTY_IMAGE_PROVIDERS` environment variable.
#### Scenario: Custom provider order
- **WHEN** `ROYALTY_IMAGE_PROVIDERS=unsplash,pexels,pixabay,wikimedia,picsum`
- **THEN** system tries providers in order: Unsplash → Pexels → Pixabay → Wikimedia → Picsum
#### Scenario: Default provider order
- **WHEN** `ROYALTY_IMAGE_PROVIDERS` is not set or empty
- **THEN** system uses default order: `pixabay,unsplash,pexels,wikimedia,picsum`
#### Scenario: Single provider configured
- **WHEN** `ROYALTY_IMAGE_PROVIDERS=pexels`
- **THEN** system only tries Pexels provider
- **AND** returns `(None, None)` if Pexels fails or is not configured
### Requirement: Sequential fallback execution
The system SHALL try providers sequentially until one returns a valid image.
#### Scenario: First provider succeeds
- **WHEN** provider chain is `pixabay,unsplash,pexels` AND Pixabay returns valid image
- **THEN** system returns Pixabay image immediately
- **AND** does NOT call Unsplash or Pexels APIs
#### Scenario: First provider fails, second succeeds
- **WHEN** provider chain is `pixabay,unsplash,pexels` AND Pixabay returns no results AND Unsplash returns valid image
- **THEN** system returns Unsplash image
- **AND** does NOT call Pexels API
#### Scenario: All providers fail
- **WHEN** all configured providers return `(None, None)`
- **THEN** system returns `(None, None)` as final result
- **AND** caller handles fallback to article image or placeholder
### Requirement: MCP endpoint override
The existing `ROYALTY_IMAGE_MCP_ENDPOINT` SHALL take priority over the provider chain when configured.
#### Scenario: MCP endpoint configured
- **WHEN** `ROYALTY_IMAGE_MCP_ENDPOINT` is set to valid URL
- **THEN** system tries MCP endpoint first before provider chain
- **AND** falls back to provider chain only if MCP endpoint fails
#### Scenario: MCP endpoint not configured
- **WHEN** `ROYALTY_IMAGE_MCP_ENDPOINT` is empty or unset
- **THEN** system skips MCP endpoint and proceeds directly to provider chain
### Requirement: Provider skip on missing credentials
Providers without required API keys SHALL be skipped silently.
#### Scenario: Skip unconfigured provider
- **WHEN** provider chain includes `pixabay` AND `PIXABAY_API_KEY` is not set
- **THEN** Pixabay is skipped without error
- **AND** chain continues to next provider
#### Scenario: All providers skipped
- **WHEN** no providers in chain have valid API keys configured
- **THEN** system falls back to Wikimedia (no key required) or Picsum (always available)

View File

@@ -0,0 +1,71 @@
## ADDED Requirements
### Requirement: Keyword extraction from headline
The system SHALL extract relevant keywords from article headlines for image search.
#### Scenario: Extract keywords from standard headline
- **WHEN** headline is "OpenAI Announces GPT-5 with Revolutionary Reasoning Capabilities"
- **THEN** extracted query is "OpenAI GPT-5 Revolutionary Reasoning"
- **AND** stop words like "Announces", "with", "Capabilities" are removed
#### Scenario: Handle short headline
- **WHEN** headline is "AI Breakthrough"
- **THEN** extracted query is "AI Breakthrough"
- **AND** no keywords are removed (headline too short)
#### Scenario: Handle headline with special characters
- **WHEN** headline is "Tesla's Self-Driving AI: 99.9% Accuracy Achieved!"
- **THEN** extracted query is "Tesla Self-Driving AI Accuracy"
- **AND** special characters like apostrophes, colons, and punctuation are normalized
### Requirement: Stop word removal
The system SHALL remove common English stop words from search queries.
#### Scenario: Remove articles and prepositions
- **WHEN** headline is "The Future of AI in the Healthcare Industry"
- **THEN** extracted query is "Future AI Healthcare Industry"
- **AND** "The", "of", "in", "the" are removed
#### Scenario: Preserve technical terms
- **WHEN** headline is "How Machine Learning Models Learn from Data"
- **THEN** extracted query is "Machine Learning Models Learn Data"
- **AND** technical terms "Machine", "Learning", "Models" are preserved
### Requirement: Query length limit
The system SHALL limit search query length to optimize API results.
#### Scenario: Truncate long query
- **WHEN** extracted keywords exceed 10 words
- **THEN** query is limited to first 5 most significant keywords
- **AND** remaining keywords are dropped
#### Scenario: Preserve short query
- **WHEN** extracted keywords are 5 words or fewer
- **THEN** all keywords are included in query
- **AND** no truncation occurs
### Requirement: URL-safe query encoding
The system SHALL URL-encode queries before sending to provider APIs.
#### Scenario: Encode spaces and special characters
- **WHEN** query is "AI Machine Learning"
- **THEN** encoded query is "AI+Machine+Learning" or "AI%20Machine%20Learning"
- **AND** query is safe for HTTP GET parameters
#### Scenario: Handle Unicode characters
- **WHEN** query contains Unicode like "AI für Deutschland"
- **THEN** Unicode characters are properly percent-encoded
- **AND** API request succeeds without encoding errors
### Requirement: Empty query handling
The system SHALL handle edge cases where no keywords can be extracted.
#### Scenario: Headline with only stop words
- **WHEN** headline is "The and a or but"
- **THEN** system uses fallback query "news technology"
- **AND** image search proceeds with generic query
#### Scenario: Empty headline
- **WHEN** headline is empty string or whitespace only
- **THEN** system uses fallback query "news technology"
- **AND** image search proceeds with generic query

View File

@@ -0,0 +1,79 @@
## ADDED Requirements
### Requirement: Pixabay image retrieval
The system SHALL support retrieving images from Pixabay API when `PIXABAY_API_KEY` is configured.
#### Scenario: Successful Pixabay image search
- **WHEN** Pixabay is enabled in provider chain AND query is "artificial intelligence breakthrough"
- **THEN** system sends GET request to `https://pixabay.com/api/?key={key}&q=artificial+intelligence+breakthrough&image_type=photo&per_page=3&safesearch=true`
- **AND** returns first hit's `webformatURL` as image URL
- **AND** returns credit as `"Photo by {user} on Pixabay"`
#### Scenario: Pixabay returns no results
- **WHEN** Pixabay search returns empty `hits` array
- **THEN** system returns `(None, None)` for this provider
- **AND** fallback chain continues to next provider
#### Scenario: Pixabay API key not configured
- **WHEN** `PIXABAY_API_KEY` environment variable is empty or unset
- **THEN** Pixabay provider is skipped in the fallback chain
### Requirement: Unsplash image retrieval
The system SHALL support retrieving images from Unsplash API when `UNSPLASH_ACCESS_KEY` is configured.
#### Scenario: Successful Unsplash image search
- **WHEN** Unsplash is enabled in provider chain AND query is "machine learning robot"
- **THEN** system sends GET request to `https://api.unsplash.com/search/photos?query=machine+learning+robot&per_page=3` with header `Authorization: Client-ID {key}`
- **AND** returns first result's `urls.regular` as image URL
- **AND** returns credit as `"Photo by {user.name} on Unsplash"`
#### Scenario: Unsplash returns no results
- **WHEN** Unsplash search returns empty `results` array
- **THEN** system returns `(None, None)` for this provider
- **AND** fallback chain continues to next provider
#### Scenario: Unsplash API key not configured
- **WHEN** `UNSPLASH_ACCESS_KEY` environment variable is empty or unset
- **THEN** Unsplash provider is skipped in the fallback chain
### Requirement: Pexels image retrieval
The system SHALL support retrieving images from Pexels API when `PEXELS_API_KEY` is configured.
#### Scenario: Successful Pexels image search
- **WHEN** Pexels is enabled in provider chain AND query is "tech startup office"
- **THEN** system sends GET request to `https://api.pexels.com/v1/search?query=tech+startup+office&per_page=3` with header `Authorization: {key}`
- **AND** returns first photo's `src.large` as image URL
- **AND** returns credit as `"Photo by {photographer} on Pexels"`
#### Scenario: Pexels returns no results
- **WHEN** Pexels search returns empty `photos` array
- **THEN** system returns `(None, None)` for this provider
- **AND** fallback chain continues to next provider
#### Scenario: Pexels API key not configured
- **WHEN** `PEXELS_API_KEY` environment variable is empty or unset
- **THEN** Pexels provider is skipped in the fallback chain
### Requirement: Provider timeout handling
Each provider API call SHALL timeout after 15 seconds.
#### Scenario: Provider request timeout
- **WHEN** provider API does not respond within 15 seconds
- **THEN** system logs timeout warning
- **AND** returns `(None, None)` for this provider
- **AND** fallback chain continues to next provider
### Requirement: Provider error handling
The system SHALL gracefully handle provider API errors without crashing.
#### Scenario: Provider returns HTTP error
- **WHEN** provider API returns 4xx or 5xx status code
- **THEN** system logs error with status code
- **AND** returns `(None, None)` for this provider
- **AND** fallback chain continues to next provider
#### Scenario: Provider returns malformed response
- **WHEN** provider API returns invalid JSON or unexpected schema
- **THEN** system logs parsing error
- **AND** returns `(None, None)` for this provider
- **AND** fallback chain continues to next provider