SPB Git

wp-spboucher-ai: initial release of the Research Working Papers observatory

Next.js 16 + PostgreSQL 17/pgvector platform for wp.spboucher.ai: publication library (permanent identifiers,
versioned manuscripts, citations), discovery (filters, hybrid search, topics/methods/datasets/authors, timeline,
research map), administration (auth, ingestion queue, versions, taxonomy, audit), public API, OAI-PMH, RSS, backups.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simon-Pierre Boucher committed (Nov 2, 2026) Browse files

149 changed files +9,812 −0

149 changed files
added .env.example +19 −0
@@ -0,0 +1,19 @@
1+APP_URL=https://wp.spboucher.ai
2+PORT=8560
3+NODE_ENV=production
4+DATABASE_URL_ADMIN=postgres://<superuser>@localhost:5432/wp_spboucher
5+DATABASE_URL=postgres://wp_app:<pw>@localhost:5432/wp_spboucher
6+DATABASE_URL_PUBLIC=postgres://wp_reader:<pw>@localhost:5432/wp_spboucher
7+SESSION_SECRET=<64 random chars>
8+OWNER_EMAIL=owner@example.org
9+OWNER_INITIAL_PASSWORD=<initial password, must be changed at first login>
10+STORAGE_DIR=/Users/<user>/data/wp-spboucher-ai
11+AI_PROVIDER=none # none | openai (embeddings only; the platform works without AI)
12+OPENAI_API_KEY=
13+OPENAI_EMBEDDING_MODEL=text-embedding-3-small
14+AI_MONTHLY_BUDGET_USD=10
15+BACKUP_DIR=/Users/<user>/backups/wp-spboucher-ai
16+BACKUP_PASSPHRASE=<passphrase>
17+BACKUP_REMOTE= # optional rsync target host:path
18+PG_BIN=/opt/homebrew/opt/postgresql@17/bin
19+WORKER_POLL_MS=5000
added .gitignore +14 −0
@@ -0,0 +1,14 @@
1+node_modules/
2+.next/
3+.env
4+.env.*
5+!.env.example
6+tsconfig.tsbuildinfo
7+next-env.d.ts
8+test-results/
9+playwright-report/
10+storage/
11+backups/
12+*.log
13+.DS_Store
14+docs/_verification-*.json
added CLAUDE.md +25 −0
@@ -0,0 +1,25 @@
1+# wp-spboucher-ai — Research Working Papers (wp.spboucher.ai)
2+
3+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.
4+
5+**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`).
6+
7+## Map
8+- `drizzle/*.sql` — schema (checksummed SQL migrations, `scripts/migrate.ts`); `public_*` views are the only objects the read-only role sees.
9+- `src/db` — postgres-js clients: `sql` (app role) / `sqlPublic` (read-only role; all public pages and API).
10+- `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.
11+- `src/lib/pdf` — poppler pipeline (pdfinfo/pdftotext/pdftoppm), SHA-256 content-addressed storage, metadata proposal heuristics (suggestions only), chunking.
12+- `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`.
13+- `src/app/(public)/[locale]` — public pages; canonical URLs are unprefixed EN, FR under `/fr/...` (rewrite in `src/proxy.ts`, separate caches).
14+- `src/app/admin` + `src/lib/admin/actions.ts` — administration (session cookie, Argon2id, TOTP, CSRF, same-origin, audit log).
15+- `src/app/api` — public API v1, files (range, ETag, download counting), OAI-PMH, events beacon, health, admin upload.
16+- `content/seed` — verified catalog (from www.spboucher.ai, 2026-11-01) + editorial taxonomy; `pnpm seed:import --publish` is idempotent.
17+
18+## Rules
19+- Never fabricate metadata; dates keep their precision (`day|month|year`); reserved identifiers (WP39, WP40) stay non-public until approved in `/admin`.
20+- Working paper numbers are permanent; redirects table handles historical slugs.
21+- Statistics are computed live; relations inferred from similarity are flagged `inferred`.
22+- Secrets only in `.env` (node) and `~/Desktop/Cluster/secrets/wp-spboucher-ai/.env` (laptop copy).
23+
24+## Commands
25+`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`.
added README.md +28 −0
@@ -0,0 +1,28 @@
1+# Research Working Papers — Simon-Pierre Boucher Research Observatory
2+
3+Public scientific publishing platform for the UQO working papers of Simon-Pierre Boucher: **https://wp.spboucher.ai**.
4+
5+Three layers: a **publication library** (stable identifiers, versioned manuscripts, rich metadata, citation exports), a **discovery engine** (topics, methods, datasets, authors, timeline, typo-tolerant and semantic search) and a **research-intelligence layer** (knowledge graph of papers linked by methods, data, topics, authors and labelled textual similarity).
6+
7+| | |
8+|---|---|
9+| Stack | Next.js 16 (App Router, React 19, TypeScript, Tailwind 4), PostgreSQL 17 + pgvector + pg_trgm + unaccent, postgres-js, poppler, PM2, OpenAI embeddings (optional) |
10+| Node | MacLustr **M3U96b** (`~/apps/wp-spboucher-ai`), deployed with `mld`; public route through the MacLustr Tunnel (BHS64, Caddy, Let's Encrypt) |
11+| Languages | English (canonical URLs) and French (`/fr/...`) |
12+| Discoverability | Highwire Press (Google Scholar) + Dublin Core meta tags, JSON-LD `ScholarlyArticle`, OAI-PMH (`/api/oai`), RSS (`/feed.xml`), sitemap, public JSON API (`/api/docs`) |
13+| Administration | `/admin` — password (Argon2id) + optional TOTP, CSRF, audit trail, ingestion queue, versions, taxonomy, settings, analytics, backups |
14+
15+## Development
16+
17+```bash
18+pnpm install
19+cp .env.example .env # fill in (see docs/operations.md)
20+pnpm db:migrate && pnpm db:roles && pnpm bootstrap
21+pnpm seed:import --publish # verified catalog + manuscripts from $STORAGE_DIR/inbox
22+pnpm worker # in another terminal
23+pnpm dev # http://localhost:8560
24+```
25+
26+Tests: `pnpm test` (unit), `pnpm test:e2e` (Playwright, set `E2E_BASE_URL`), `pnpm test:security [url]`, `pnpm verify:deploy [url]`.
27+
28+Documentation: `docs/infrastructure-report.md` (discovery and compatibility), `docs/architecture.md`, `docs/operations.md` (runbook), `docs/api.md`, `docs/verification.md` (test evidence).
added content/seed/catalog.json +5567 −0
Large diff (5,568 lines) is not loaded by default to keep the page fast.Load diff
added content/seed/taxonomy.json +200 −0
Large diff (200 lines) is not loaded by default to keep the page fast.Load diff
added docs/api.md +15 −0
Large diff (15 lines) is not loaded by default to keep the page fast.Load diff
added docs/architecture.md +32 −0
Large diff (32 lines) is not loaded by default to keep the page fast.Load diff
added docs/infrastructure-report.md +20 −0
Large diff (20 lines) is not loaded by default to keep the page fast.Load diff
added docs/operations.md +44 −0
Large diff (44 lines) is not loaded by default to keep the page fast.Load diff
added docs/verification.md +3 −0
Large diff (3 lines) is not loaded by default to keep the page fast.Load diff
added drizzle/0001_init.sql +279 −0
Large diff (279 lines) is not loaded by default to keep the page fast.Load diff
added drizzle/0002_roles.sql +17 −0
Large diff (17 lines) is not loaded by default to keep the page fast.Load diff
added infra/mld/wp-spboucher-ai.json +34 −0
Large diff (34 lines) is not loaded by default to keep the page fast.Load diff
added next.config.ts +44 −0
Large diff (44 lines) is not loaded by default to keep the page fast.Load diff
added package.json +54 −0
Large diff (54 lines) is not loaded by default to keep the page fast.Load diff
added playwright.config.ts +10 −0
Large diff (10 lines) is not loaded by default to keep the page fast.Load diff
added pnpm-workspace.yaml +6 −0
Large diff (6 lines) is not loaded by default to keep the page fast.Load diff
added postcss.config.mjs +1 −0
Large diff (1 lines) is not loaded by default to keep the page fast.Load diff
added scripts/_admin-sql.ts +8 −0
Large diff (8 lines) is not loaded by default to keep the page fast.Load diff
added scripts/_env.ts +6 −0
Large diff (6 lines) is not loaded by default to keep the page fast.Load diff
added scripts/backup.ts +3 −0
Large diff (3 lines) is not loaded by default to keep the page fast.Load diff
added scripts/bootstrap-owner.ts +22 −0
Large diff (22 lines) is not loaded by default to keep the page fast.Load diff
added scripts/db-roles.ts +7 −0
Large diff (7 lines) is not loaded by default to keep the page fast.Load diff
added scripts/ingest-scan.ts +4 −0
Large diff (4 lines) is not loaded by default to keep the page fast.Load diff
added scripts/migrate.ts +20 −0
Large diff (20 lines) is not loaded by default to keep the page fast.Load diff
added scripts/relations-rebuild.ts +4 −0
Large diff (4 lines) is not loaded by default to keep the page fast.Load diff
added scripts/restore-drill.ts +18 −0
Large diff (18 lines) is not loaded by default to keep the page fast.Load diff
added scripts/security-audit.ts +27 −0
Large diff (27 lines) is not loaded by default to keep the page fast.Load diff
added scripts/seed-import.ts +105 −0
Large diff (105 lines) is not loaded by default to keep the page fast.Load diff
added scripts/verify-deploy.ts +20 −0
Large diff (20 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(auth)/login/actions.ts +31 −0
Large diff (31 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(auth)/login/page.tsx +24 −0
Large diff (24 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/about/page.tsx +31 −0
Large diff (31 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/api/docs/page.tsx +14 −0
Large diff (14 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/authors/[slug]/page.tsx +18 −0
Large diff (18 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/authors/page.tsx +12 −0
Large diff (12 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/citation/page.tsx +21 −0
Large diff (21 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/datasets/[slug]/page.tsx +17 −0
Large diff (17 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/datasets/page.tsx +17 −0
Large diff (17 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/layout.tsx +18 −0
Large diff (18 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/methods/[slug]/page.tsx +13 −0
Large diff (13 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/methods/page.tsx +17 −0
Large diff (17 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/page.tsx +69 −0
Large diff (69 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/papers/[id]/[version]/page.tsx +33 −0
Large diff (33 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/papers/[id]/page.tsx +127 −0
Large diff (127 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/papers/[id]/read/page.tsx +20 −0
Large diff (20 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/papers/page.tsx +75 −0
Large diff (75 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/research-map/page.tsx +12 −0
Large diff (12 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/search/page.tsx +21 −0
Large diff (21 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/series/page.tsx +16 −0
Large diff (16 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/timeline/page.tsx +18 −0
Large diff (18 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/topics/[slug]/page.tsx +21 −0
Large diff (21 lines) is not loaded by default to keep the page fast.Load diff
added src/app/(public)/[locale]/topics/page.tsx +20 −0
Large diff (20 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/account/page.tsx +20 −0
Large diff (20 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/analytics/page.tsx +17 −0
Large diff (17 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/audit/page.tsx +9 −0
Large diff (9 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/ingest/[id]/page.tsx +39 −0
Large diff (39 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/ingest/page.tsx +15 −0
Large diff (15 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/layout.tsx +22 −0
Large diff (22 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/page.tsx +17 −0
Large diff (17 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/papers/[id]/page.tsx +36 −0
Large diff (36 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/papers/[id]/upload-form.tsx +20 −0
Large diff (20 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/papers/new/page.tsx +7 −0
Large diff (7 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/papers/page.tsx +10 −0
Large diff (10 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/papers/paper-form.tsx +53 −0
Large diff (53 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/settings/page.tsx +17 −0
Large diff (17 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/system/page.tsx +17 −0
Large diff (17 lines) is not loaded by default to keep the page fast.Load diff
added src/app/admin/taxonomy/page.tsx +29 −0
Large diff (29 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/admin/preview/[sha]/route.ts +10 −0
Large diff (10 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/admin/upload/route.ts +36 −0
Large diff (36 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/events/route.ts +12 −0
Large diff (12 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/files/[fileId]/[name]/route.ts +26 −0
Large diff (26 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/health/route.ts +6 −0
Large diff (6 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/oai/route.ts +42 −0
Large diff (42 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/preview/[name]/route.ts +13 −0
Large diff (13 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/v1/authors/route.ts +3 −0
Large diff (3 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/v1/datasets/route.ts +3 −0
Large diff (3 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/v1/graph/route.ts +3 −0
Large diff (3 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/v1/methods/route.ts +3 −0
Large diff (3 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/v1/openapi.json/route.ts +2 −0
Large diff (2 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/v1/papers/[id]/citation.[format]/route.ts +13 −0
Large diff (13 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/v1/papers/[id]/route.ts +9 −0
Large diff (9 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/v1/papers/route.ts +10 −0
Large diff (10 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/v1/search/route.ts +9 −0
Large diff (9 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/v1/series/route.ts +3 −0
Large diff (3 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/v1/stats/route.ts +3 −0
Large diff (3 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/v1/timeline/route.ts +3 −0
Large diff (3 lines) is not loaded by default to keep the page fast.Load diff
added src/app/api/v1/topics/route.ts +3 −0
Large diff (3 lines) is not loaded by default to keep the page fast.Load diff
added src/app/feed.xml/route.ts +13 −0
Large diff (13 lines) is not loaded by default to keep the page fast.Load diff
added src/app/globals.css +64 −0
Large diff (64 lines) is not loaded by default to keep the page fast.Load diff
added src/app/layout.tsx +25 −0
Large diff (25 lines) is not loaded by default to keep the page fast.Load diff
added src/app/not-found.tsx +7 −0
Large diff (7 lines) is not loaded by default to keep the page fast.Load diff
added src/app/robots.ts +5 −0
Large diff (5 lines) is not loaded by default to keep the page fast.Load diff
added src/app/sitemap.ts +14 −0
Large diff (14 lines) is not loaded by default to keep the page fast.Load diff
added src/components/admin-ui.tsx +20 −0
Large diff (20 lines) is not loaded by default to keep the page fast.Load diff
added src/components/cite-menu.tsx +25 −0
Large diff (25 lines) is not loaded by default to keep the page fast.Load diff
added src/components/constellation.tsx +60 −0
Large diff (60 lines) is not loaded by default to keep the page fast.Load diff
added src/components/display-toggle.tsx +19 −0
Large diff (19 lines) is not loaded by default to keep the page fast.Load diff
added src/components/pagination.tsx +12 −0
Large diff (12 lines) is not loaded by default to keep the page fast.Load diff
added src/components/paper-items.tsx +73 −0
Large diff (73 lines) is not loaded by default to keep the page fast.Load diff
added src/components/site-footer.tsx +31 −0
Large diff (31 lines) is not loaded by default to keep the page fast.Load diff
added src/components/site-header.tsx +43 −0
Large diff (43 lines) is not loaded by default to keep the page fast.Load diff
added src/components/stat-tiles.tsx +14 −0
Large diff (14 lines) is not loaded by default to keep the page fast.Load diff
added src/components/theme-toggle.tsx +9 −0
Large diff (9 lines) is not loaded by default to keep the page fast.Load diff
added src/components/view-beacon.tsx +7 −0
Large diff (7 lines) is not loaded by default to keep the page fast.Load diff
added src/db/index.ts +14 −0
Large diff (14 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/admin/actions.ts +174 −0
Large diff (174 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/admin/queries.ts +38 −0
Large diff (38 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/ai/embeddings.ts +29 −0
Large diff (29 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/ai/lexvec.ts +17 −0
Large diff (17 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/api.ts +8 −0
Large diff (8 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/audit.ts +5 −0
Large diff (5 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/auth/attempts.ts +14 −0
Large diff (14 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/auth/guard.ts +48 −0
Large diff (48 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/auth/password.ts +10 −0
Large diff (10 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/auth/ratelimit.ts +9 −0
Large diff (9 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/auth/session.ts +53 −0
Large diff (53 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/env.ts +7 −0
Large diff (7 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/i18n/en.ts +22 −0
Large diff (22 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/i18n/fr.ts +22 −0
Large diff (22 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/i18n/index.ts +32 −0
Large diff (32 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/i18n/server.ts +6 −0
Large diff (6 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/jobs/backup.ts +37 −0
Large diff (37 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/jobs/handlers.ts +156 −0
Large diff (156 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/jobs/queue.ts +23 −0
Large diff (23 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/jobs/relations.ts +41 −0
Large diff (41 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/papers/citation.ts +58 −0
Large diff (58 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/papers/events.ts +14 −0
Large diff (14 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/papers/identifiers.ts +27 −0
Large diff (27 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/papers/meta.ts +33 −0
Large diff (33 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/papers/openapi.ts +23 −0
Large diff (23 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/papers/params.ts +7 −0
Large diff (7 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/papers/queries.ts +129 −0
Large diff (129 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/papers/search.ts +50 −0
Large diff (50 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/papers/types.ts +25 −0
Large diff (25 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/pdf/chunk.ts +16 −0
Large diff (16 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/pdf/extract.ts +57 −0
Large diff (57 lines) is not loaded by default to keep the page fast.Load diff
added src/lib/pdf/process.ts +54 −0
Large diff (54 lines) is not loaded by default to keep the page fast.Load diff
added src/proxy.ts +24 −0
Large diff (24 lines) is not loaded by default to keep the page fast.Load diff
added src/worker/index.ts +36 −0
Large diff (36 lines) is not loaded by default to keep the page fast.Load diff
added tests/e2e/admin.spec.ts +17 −0
Large diff (17 lines) is not loaded by default to keep the page fast.Load diff
added tests/e2e/public.spec.ts +48 −0
Large diff (48 lines) is not loaded by default to keep the page fast.Load diff
added tests/unit/citation.test.ts +13 −0
Large diff (13 lines) is not loaded by default to keep the page fast.Load diff
added tests/unit/extract.test.ts +28 −0
Large diff (28 lines) is not loaded by default to keep the page fast.Load diff
added tests/unit/i18n.test.ts +12 −0
Large diff (12 lines) is not loaded by default to keep the page fast.Load diff
added tests/unit/identifiers.test.ts +23 −0
Large diff (23 lines) is not loaded by default to keep the page fast.Load diff
added tsconfig.json +45 −0
Large diff (45 lines) is not loaded by default to keep the page fast.Load diff
added vitest.config.ts +6 −0
Large diff (7 lines) is not loaded by default to keep the page fast.Load diff
Menu

Theme