# wp-spboucher-ai — Research Working Papers (wp.spboucher.ai) Public working-paper observatory of Simon-Pierre Boucher (UQO). Deployed on MacLustr node **M3U96b** by `mld` (app `wp-spboucher-ai`, PM2 `wp-web` :8560 + `wp-worker`, Postgres 17 DB `wp_spboucher`, manuscripts in `~/data/wp-spboucher-ai`). Public route: BHS64 Caddy → wg1 M3U96b:8560. **Remote-first**: the source of truth is the clone on the node (`M3U96b:~/apps/wp-spboucher-ai`, origin spbgit `wp-spboucher-ai.git`). Edit there, `pnpm build && pm2 restart wp-web wp-worker`, then commit/push on the node; `git pull` on the laptop mirror (`~/Desktop/Cluster/projets/wp-spboucher-ai`). ## Map - `drizzle/*.sql` — schema (checksummed SQL migrations, `scripts/migrate.ts`); `public_*` views are the only objects the read-only role sees. - `src/db` — postgres-js clients: `sql` (app role) / `sqlPublic` (read-only role; all public pages and API). - `src/lib/papers` — public queries, hybrid search (tsvector + trigram + pgvector RRF), citations (APA/Chicago/BibTeX/RIS), identifiers (`WP38` ⇄ `wp38`, permanent), Scholar/DC/JSON-LD meta, OpenAPI. - `src/lib/pdf` — poppler pipeline (pdfinfo/pdftotext/pdftoppm), SHA-256 content-addressed storage, metadata proposal heuristics (suggestions only), chunking. - `src/lib/jobs` — worker handlers: `process_pdf`, `embed_paper` (OpenAI, optional, model verified at runtime), `relations` (deterministic + inferred, labelled), `daily_stats`, `backup` (pg_dump + tar, AES-256, 14 d, rsync), `ingest_scan` / `ingest_candidate`. - `src/app/(public)/[locale]` — public pages; canonical URLs are unprefixed EN, FR under `/fr/...` (rewrite in `src/proxy.ts`, separate caches). - `src/app/admin` + `src/lib/admin/actions.ts` — administration (session cookie, Argon2id, TOTP, CSRF, same-origin, audit log). - `src/app/api` — public API v1, files (range, ETag, download counting), OAI-PMH, events beacon, health, admin upload. - `content/seed` — verified catalog (from www.spboucher.ai, 2026-11-01) + editorial taxonomy; `pnpm seed:import --publish` is idempotent. ## Rules - Never fabricate metadata; dates keep their precision (`day|month|year`); reserved identifiers (WP39, WP40) stay non-public until approved in `/admin`. - Working paper numbers are permanent; redirects table handles historical slugs. - Statistics are computed live; relations inferred from similarity are flagged `inferred`. - Secrets only in `.env` (node) and `~/Desktop/Cluster/secrets/wp-spboucher-ai/.env` (laptop copy). ## Commands `pnpm test` (vitest) · `pnpm test:e2e` (Playwright, `E2E_BASE_URL`) · `pnpm test:security [url]` · `pnpm verify:deploy [url]` · `pnpm backup` · `pnpm restore:drill` · `pnpm ingest:scan [dir]` · `pnpm relations:rebuild`.