← back to Ventura Corridor
src/jobs/auto_publish_top.ts
40 lines
/**
* Nightly auto-publish: take the top-N most-viewed drafts/reviewed features and
* flip them to status='published'. Keeps the public /issue growing without
* Steve having to manually curate every feature.
*
* $ npx tsx src/jobs/auto_publish_top.ts # default top 10
* $ npx tsx src/jobs/auto_publish_top.ts 25 # top 25
*/
import 'dotenv/config';
import { pool, query } from '../../db/pool.ts';
const N = parseInt(process.argv.find(a => /^\d+$/.test(a)) || '10', 10);
const MIN_LEN = parseInt(process.env.MIN_LEN || '160', 10);
async function main() {
// Pick: status NOT yet published, editorial decent length, sort by views desc + recency
const r = await query(
`WITH picks AS (
SELECT mf.id
FROM magazine_features mf
WHERE mf.status IN ('draft', 'reviewed')
AND length(mf.editorial) >= $2
ORDER BY mf.views DESC, mf.generated_at DESC
LIMIT $1
)
UPDATE magazine_features
SET status = 'published', published_at = NOW(), reviewed_at = COALESCE(reviewed_at, NOW())
WHERE id IN (SELECT id FROM picks)
RETURNING id, headline`,
[N, MIN_LEN]
);
console.log(`[auto_publish_top] published ${r.rowCount} features (top ${N} by views, min editorial ${MIN_LEN} chars)`);
for (const row of r.rows) {
console.log(` ★ ${row.id} ${(row.headline || '').slice(0, 60)}`);
}
await pool.end();
}
main().catch(e => { console.error(e); process.exit(1); });