# BidaAngMamayan **BIDA ANG MAMAMAYAN** — a public supporter tribute news desk for **Senator Bam Aquino**, the gamer of the Philippine Senate and champion of college students, scholarships, and fair electricity. > Forked from the Forthena architecture (Next.js + Mongo + an RSS crawler), > retargeted to follow ONE subject and stripped of everything a private paper > needs but a public tribute does not: **no login, no accounts, no > like/dislike, no per-reader AI.** --- ## What it is - **A live news crawl** (every 15 min, PM2 cron) that follows every story on the Philippine wire that *names* Sen. Bam Aquino, plus a quiet-day fallback to general PH wires. A **relevance gate** drops the senator's name from unrelated copy — only genuine BAM stories print. - **A yellow/gamer visual motif** (Orbitron + Rajdhani + JetBrains Mono, CRT scanlines, an XP-bar edition meter, a scrolling BAM-wire ticker, a neon "LIVE DESK" HUD) — because the senator is a gamer. - **A public community board — "Thank you, Senator BAM"** — visitors post with a **nickname only** (no account, no email). Light abuse controls: per-IP rate limit, hard content caps, markup stripping, URL-only rejection. - **An in-page reader drawer** that lifts the full article body server-side (Readability) so a story can be read without leaving the site, with an honest "read at source" fallback when a publisher blocks us. - **A disclaimer, always visible** (masthead + footer): the site is run by *supporters* and is **not affiliated with, endorsed by, or operated by** the senator or his office. ## The seven desks `BAM Front` (lead, named-BAM) · `Education` · `Energy & Electricity` · `Gamer's Corner` · `The Senate Floor` · `The Philippines` · `World`. ## Stack Next.js 15 (React 19, App Router, plain CSS — no Tailwind in the UI), MongoDB 7.0, PM2, nginx + Let's Encrypt. **No LLM in the runtime path** — ranking is deterministic (`named` → fresh → photo). The Forthena llmrouter dependency was removed entirely. ## Run locally ```bash npm install # point at a Mongo (defaults to mongodb://127.0.0.1:27017/bama) npm run build npm start # :3000 ``` Tests: ```bash bash tests/run-all.sh # self-contained (no Mongo) MONGODB_URI=mongodb://127.0.0.1:27099/bama node tests/board-test.mjs node tests/e2e-run.mjs # boots the built app on :4003 ``` ## Deploy (manual — no CI, by owner order) Target box: **66.181.46.132**, domain **bidaangmamamayan.com** (apex + www). 1. On the box, `/var/www/bama` holds the source. `.env.production` lives **only on the box** (never rsync it): `MONGODB_URI`, `CRON_SECRET`. 2. `rsync -az --delete --exclude node_modules --exclude .next --exclude .git --exclude '.env*' ./ root@66.181.46.132:/var/www/bama/` 3. On the box: `cd /var/www/bama && npm ci && npm run build && pm2 reload bama` 4. Crawl tick is PM2 app `bama-crawl` (`*/15 * * * *` → `POST /api/crawl` with `x-bama-cron=$CRON_SECRET`). First edition appears within ~15 min; fire one crawl by hand to seed it immediately. 5. TLS: `certbot --nginx -d bidaangmamamayan.com -d www.bidaangmamamayan.com` (nginx is already configured for both; the 443 block is live once the cert exists). Auto-renewal timer is armed by certbot. Mongo note: the box runs kernel 7.0 (Ubuntu 26.04) where Mongo 8.x is broken (8.0 refuses the kernel, 8.2 SIGSEGVs). **MongoDB 7.0 from the jammy channel is the working version** — installed at provision time. ## Files that matter | path | role | | --- | --- | | `lib/sources.js` | the BAM query registry + Bing feed helpers | | `lib/crawl.js` | crawler + **relevance gate** (`bamRelevance`) | | `lib/categories.js` | the 7-desk registry (single source of truth) | | `lib/feed.js` | public edition: deterministic rank, desk headlines, stats | | `lib/article.js` | reader extraction (Readability + honest fallbacks) | | `lib/board.js` | community board: caps, sanitise, rate limit | | `app/page.js` | the whole front-end (client SPA: views + reader drawer) | | `app/globals.css` | the yellow/gamer theme | | `ecosystem.config.cjs` | PM2 apps (`bama`, `bama-crawl`) | --- *A fan project. Bida ang Mamamayan.* 🎮