Initial Commit

This commit is contained in:
2026-02-12 16:50:29 -05:00
commit a1da041f14
74 changed files with 6140 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
## ADDED Requirements
### Requirement: Containerized deployment
The system SHALL run entirely within Docker containers with all dependencies included.
#### Scenario: Single container build
- **WHEN** building the Docker image
- **THEN** the Dockerfile SHALL include Python runtime, Node.js (for Tailwind if needed), and all application code
- **AND** expose port 8000 for web traffic
#### Scenario: Environment configuration
- **WHEN** running the container
- **THEN** the system SHALL read PERPLEXITY_API_KEY from environment variables
- **AND** fail to start if the key is missing or invalid
- **AND** support optional configuration for retention days (default: 30)
- **AND** support optional IMAGE_QUALITY for image compression (default: 85)
- **AND** support optional OPENROUTER_API_KEY for fallback LLM provider
- **AND** support optional UMAMI_SCRIPT_URL and UMAMI_WEBSITE_ID for analytics
#### Scenario: Data persistence
- **WHEN** the container restarts
- **THEN** the SQLite database SHALL persist via Docker volume mount
- **AND** news data SHALL remain intact across restarts
## ADDED Requirements
### Requirement: Responsive single-page design
The system SHALL provide a stunning, responsive one-page website with ClawFort branding.
#### Scenario: Brand consistency
- **WHEN** viewing the website
- **THEN** the design SHALL feature ClawFort branding (logo, colors, typography)
- **AND** maintain visual consistency across all sections
#### Scenario: Responsive layout
- **WHEN** viewing on mobile, tablet, or desktop
- **THEN** the layout SHALL adapt appropriately
- **AND** the hero block SHALL resize proportionally
- **AND** the news feed SHALL use appropriate column layouts
#### Scenario: Performance
- **WHEN** loading the page
- **THEN** initial page load SHALL complete within 2 seconds
- **AND** images SHALL lazy load outside viewport
- **AND** JavaScript bundle SHALL be under 100KB gzipped

View File

@@ -0,0 +1,55 @@
## ADDED Requirements
### Requirement: Hero block display
The system SHALL display the most recent news item as a featured hero block with full attribution.
#### Scenario: Hero rendering
- **WHEN** the page loads
- **THEN** the hero block SHALL display the latest news headline, summary, and featured image
- **AND** show source attribution (e.g., "Via: TechCrunch")
- **AND** show image credit (e.g., "Image: DALL-E")
#### Scenario: Hero update
- **WHEN** new news is fetched hourly
- **THEN** the hero block SHALL automatically update to show the newest item
- **AND** the previous hero item SHALL move to the news feed
## ADDED Requirements
### Requirement: Infinite scroll news feed
The system SHALL display news items in reverse chronological order with infinite scroll pagination.
#### Scenario: Initial load
- **WHEN** the page first loads
- **THEN** the system SHALL display the 10 most recent non-archived news items
- **AND** exclude the hero item from the feed
#### Scenario: Infinite scroll
- **WHEN** the user scrolls to the bottom of the feed
- **THEN** the system SHALL fetch the next 10 news items via API
- **AND** append them to the feed without page reload
- **AND** show a loading indicator during fetch
#### Scenario: End of feed
- **WHEN** all non-archived news items have been loaded
- **THEN** the system SHALL display "No more news" message
- **AND** disable further scroll triggers
### Requirement: News attribution display
The system SHALL clearly attribute all news content and images to their sources.
#### Scenario: Source attribution
- **WHEN** displaying any news item
- **THEN** the system SHALL show the original source name and link
- **AND** display image credit if available
#### Scenario: Perplexity attribution
- **WHEN** displaying aggregated content
- **THEN** the system SHALL include "Powered by Perplexity" in the footer
#### Scenario: Analytics tracking
- **WHEN** Umami analytics is configured via `UMAMI_SCRIPT_URL` and `UMAMI_WEBSITE_ID`
- **THEN** the system SHALL inject Umami tracking script into page head
- **AND** track page view events on initial load
- **AND** track scroll depth events (25%, 50%, 75%, 100%)
- **AND** track CTA click events (news item clicks, source link clicks)

View File

@@ -0,0 +1,56 @@
## ADDED Requirements
### Requirement: News aggregation via Perplexity API
The system SHALL fetch AI news hourly from Perplexity API and store it with full attribution.
#### Scenario: Hourly news fetch
- **WHEN** the scheduled job runs every hour
- **THEN** the system calls Perplexity API with query "latest AI news"
- **AND** stores the response with headline, summary, source URL, and timestamp
#### Scenario: API error handling
- **WHEN** Perplexity API returns an error or timeout
- **THEN** the system logs the error with cost tracking
- **AND** retries with exponential backoff up to 3 times
- **AND** falls back to OpenRouter API if `OPENROUTER_API_KEY` is configured
- **AND** continues using cached content if all retries and fallback fail
### Requirement: Featured image generation
The system SHALL generate or fetch a relevant featured image for each news item.
#### Scenario: Image acquisition
- **WHEN** a new news item is fetched
- **THEN** the system SHALL request a relevant image URL from Perplexity
- **AND** download and optimize the image locally using Pillow
- **AND** apply quality compression based on `IMAGE_QUALITY` env var (1-100, default 85)
- **AND** store the optimized image path and original image credit/source information
#### Scenario: Image optimization configuration
- **WHEN** the system processes an image
- **THEN** it SHALL read `IMAGE_QUALITY` from environment (default: 85)
- **AND** apply JPEG compression at specified quality level
- **AND** resize images exceeding 1200px width while maintaining aspect ratio
- **AND** store optimized images in `/app/static/images/` directory
#### Scenario: Image fallback
- **WHEN** image generation fails or returns no result
- **THEN** the system SHALL use a default ClawFort branded placeholder image
## ADDED Requirements
### Requirement: News data persistence with retention
The system SHALL store news items for exactly 30 days with automatic archiving.
#### Scenario: News storage
- **WHEN** a news item is fetched from Perplexity
- **THEN** the system SHALL store it in SQLite with fields: id, headline, summary, source_url, image_url, image_credit, published_at, created_at
- **AND** set archived=false by default
#### Scenario: Automatic archiving
- **WHEN** a nightly cleanup job runs
- **THEN** the system SHALL mark all news items older than 30 days as archived=true
- **AND** delete archived items older than 60 days permanently
#### Scenario: Duplicate prevention
- **WHEN** fetching news that matches an existing headline (within 24 hours)
- **THEN** the system SHALL skip insertion to prevent duplicates