[ci skip] Flatten module wrappers into stack roots
Remove the module "xxx" { source = "./module" } indirection layer
from all 66 service stacks. Resources are now defined directly in
each stack's main.tf instead of through a wrapper module.
- Merge module/main.tf contents into stack main.tf
- Apply variable replacements (var.tier -> local.tiers.X, renamed vars)
- Fix shared module paths (one fewer ../ at each level)
- Move extra files/dirs (factory/, chart_values, subdirs) to stack root
- Update state files to strip module.<name>. prefix
- Update CLAUDE.md to reflect flat structure
Verified: terragrunt plan shows 0 add, 0 destroy across all stacks.
This commit is contained in:
parent
b0499a7f31
commit
c7c7047f1c
245 changed files with 11733 additions and 12432 deletions
|
|
@ -1,78 +0,0 @@
|
|||
# F1 Stream
|
||||
|
||||
## What This Is
|
||||
|
||||
A self-hosted web app that aggregates live Formula 1 streaming links from Reddit and user submissions, presenting them in a clean UI with embedded iframes. It scrapes r/motorsportsstreams2, allows users to submit their own stream URLs, and provides admin controls for content moderation. Built in Go with vanilla JS frontend, deployed on Kubernetes.
|
||||
|
||||
## Core Value
|
||||
|
||||
Users can find working F1 streams quickly — the app automatically discovers, validates, and surfaces healthy streams while removing dead ones.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Validated
|
||||
|
||||
<!-- Shipped and confirmed valuable. Inferred from existing codebase. -->
|
||||
|
||||
- ✓ Reddit scraper polls r/motorsportsstreams2 for F1-related posts — existing
|
||||
- ✓ URL extraction from post bodies and comment trees — existing
|
||||
- ✓ F1 keyword filtering with negative keyword exclusion — existing
|
||||
- ✓ Domain filtering (reddit, imgur, youtube, twitter excluded) — existing
|
||||
- ✓ Deduplication via normalized URLs — existing
|
||||
- ✓ User stream submission (anonymous + authenticated) — existing
|
||||
- ✓ WebAuthn passwordless authentication — existing
|
||||
- ✓ Admin approval workflow for user-submitted streams — existing
|
||||
- ✓ HTTP proxy with rate limiting, private IP blocking, CSP stripping — existing
|
||||
- ✓ Static frontend with iframe-based stream viewing — existing
|
||||
- ✓ Default seed streams on first run — existing
|
||||
- ✓ Stale link cleanup (24h) — existing
|
||||
- ✓ Client-side health sort (reorder by reachability) — existing
|
||||
|
||||
### Active
|
||||
|
||||
<!-- Current scope. Building toward these. -->
|
||||
|
||||
- [ ] Scraper validates extracted URLs look like actual streams (video/player content), not random links
|
||||
- [ ] Server-side health checker runs every 5 minutes against all known streams
|
||||
- [ ] Health check: HTTP reachability check first, then proxy-fetch to detect video/player markers
|
||||
- [ ] Configurable health check timeout
|
||||
- [ ] Streams marked unhealthy after 5 consecutive check failures get hidden from public page
|
||||
- [ ] Unhealthy streams retried on each check cycle — restored if they recover
|
||||
- [ ] Scraped streams that pass health checks auto-published to main streams page
|
||||
- [ ] Dead streams dynamically removed from the page without manual intervention
|
||||
- [ ] Health status persisted (failure count, last check time, healthy/unhealthy state)
|
||||
|
||||
### Out of Scope
|
||||
|
||||
- Database migration (SQLite/PostgreSQL) — file-based storage is fine for this scope
|
||||
- Multiple subreddit sources — stick with r/motorsportsstreams2 for now
|
||||
- Real-time WebSocket push of stream status — polling is sufficient
|
||||
- Mobile app — web-only
|
||||
- OAuth/social login — WebAuthn is sufficient
|
||||
|
||||
## Context
|
||||
|
||||
- The app runs on a personal Kubernetes cluster, deployed via Terraform
|
||||
- Single-user / small-group usage — performance at scale is not a concern
|
||||
- The existing client-side `sortStreamsByHealth` does a basic `no-cors` fetch but can't inspect content; server-side checks via the proxy can do deeper validation
|
||||
- Reddit's public JSON API requires no auth but rate-limits aggressively; the scraper already handles 429s with backoff
|
||||
- Stream sites frequently go down, change URLs, or get taken down — health checking is essential for a good UX
|
||||
|
||||
## Constraints
|
||||
|
||||
- **Tech stack**: Go backend, vanilla JS frontend — no new frameworks or dependencies unless strictly necessary
|
||||
- **Storage**: File-based JSON — no database
|
||||
- **Deployment**: Docker container on Kubernetes, single replica
|
||||
- **Reddit API**: Public JSON endpoints, must respect rate limits (1 req/sec delay already in place)
|
||||
|
||||
## Key Decisions
|
||||
|
||||
| Decision | Rationale | Outcome |
|
||||
|----------|-----------|---------|
|
||||
| Server-side health checks over client-side only | Client can't inspect response content (CORS); server proxy can detect video markers | — Pending |
|
||||
| 5 consecutive failures before hiding | Avoids flapping — streams that are temporarily down aren't immediately removed | — Pending |
|
||||
| Auto-publish scraped streams that pass health | Reduces manual admin work; the health check is the quality gate | — Pending |
|
||||
| Health check every 5 minutes | Balances freshness vs. load — streams don't change status that frequently | — Pending |
|
||||
|
||||
---
|
||||
*Last updated: 2026-02-17 after initialization*
|
||||
Loading…
Add table
Add a link
Reference in a new issue