Forked from Forthena (PERSONAL/forthena) and retargeted: - NO login, NO LLM: the edition is public and the ranking is deterministic (stories that name Sen. BAM lead; freshest first) — Daniel: no like/dislike or store profile for visitors. - Crawler scoped to BAM: Bing news keyword queries + Inquirer/Rappler fallback wires, with a two-tier relevance gate (named-BAM always; Aquino+legislative-context only from fallback) so op-eds and non-Bam senators are dropped. - Desks: BAM (lead), Gaming, Education, Politics, Energy, PH, Business. - Community board /board: 'Thank you Senator BAM' — nickname-only posts, HTML-stripped, URL-only rejected, IP rate-limited (3/10min, 20/day). - Yellow-gamer theme (Orbitron/Rajdhani/JetBrains Mono, dark + gold, HUD corners), supporter disclaimer in header and footer. - Tests: category/date/relevance/text suites + Mongo board suite + full HTTP e2e (all passing). Infra: 66.181.46.132 (bidaangmamamayan.com), local Mongo 7.0, nginx + certbot TLS, PM2 bama (:3000) + 15-min crawl cron.
98 lines
4.2 KiB
Markdown
98 lines
4.2 KiB
Markdown
# 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.* 🎮
|