Week 4 (scoped): BooksRun live price/stock check + daily FTP sync stub

Adds a live per-ISBN BooksRun API check to the checkout-time price
recheck (Order\PriceRecheck) so a booksrun-sourced offer is verified
fresh, not trusted from a potentially day-stale local cache -- fails
closed on any problem (API error, no stock), matching Appendix B's
"stale supplier cost must never be trusted as final." Live values are
written back to the same offer_id row so SupplierOrderJob's later
fulfillment-time read sees them too.

Also wires a real daily Action Scheduler job (scheduling/dedup/batch-write
infrastructure) for BooksRun's FTP inventory feed, but leaves the actual
connect+parse step (Import\BooksRunOfferSync::connect_and_parse_feed())
as a deliberate stub -- no FTP access or sample feed exists yet, and
guessing at a file format would silently write wrong data once real
access arrives. The stub fails loud on the manual CLI trigger, quiet on
the scheduled job (no point alarming on an expected, known state).

Ingram, BooksRun AutoBuy, production email, and tax/legal/monitoring are
explicitly out of scope for this pass -- narrowed by user request.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D2gmgaDVXcRGCwLfdXQajD
This commit is contained in:
twooeyandClaude Sonnet 5 committed 2026-08-27 21:29:37 -04:00
1 parent 4079bfceac
commit a733ba4bfd
11 files changed
+578 -4

No files matched your search

+18 -3
View File
@@ -25,8 +25,9 @@
# The remaining supplier keys below are still passed the old ${VAR} way and
# remain exposed to the same class of bug — nothing consumes them yet
# (bookstore-core is still a stub for those), so when that code is written
# it should read `_FILE` variants the same way HARDCOVER_API_TOKEN and (as
# of Week 3) HELCIM_API_TOKEN now do below.
# it should read `_FILE` variants the same way HARDCOVER_API_TOKEN,
# HELCIM_API_TOKEN (Week 3), and BOOKSRUN_API_KEY/BOOKSRUN_FTP_PASSWORD
# (Week 4) now do below.
x-bookstore-env: &bookstore-env
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: ${DB_NAME}
@@ -42,13 +43,23 @@ x-bookstore-env: &bookstore-env
# Passed through for the bookstore-core plugin's supplier adapters /
# payment integration (design doc §04/§05) — not read by WordPress core.
ACTIVE_SUPPLIER_ADAPTERS: ${ACTIVE_SUPPLIER_ADAPTERS:-gutenberg_test}
BOOKSRUN_API_KEY: ${BOOKSRUN_API_KEY:-}
INGRAM_API_KEY: ${INGRAM_API_KEY:-}
INGRAM_ACCOUNT_ID: ${INGRAM_ACCOUNT_ID:-}
HELCIM_ACCOUNT_ID: ${HELCIM_ACCOUNT_ID:-}
MAILERLITE_API_KEY: ${MAILERLITE_API_KEY:-}
HARDCOVER_API_TOKEN_FILE: /run/secrets/hardcover_api_token
HELCIM_API_TOKEN_FILE: /run/secrets/helcim_api_token
BOOKSRUN_API_KEY_FILE: /run/secrets/booksrun_api_key
# Week 4: bulk FTP inventory feed connection details — BOOKSRUN_FTP_HOST
# empty means Import\BooksRunOfferSync::is_ftp_configured() is false and
# the daily sync job stays a no-op (see that class). None of these are
# read by any code path yet beyond that one boolean check — the actual
# connect+parse logic is still a stub pending real access/a sample feed.
BOOKSRUN_FTP_HOST: ${BOOKSRUN_FTP_HOST:-}
BOOKSRUN_FTP_PORT: ${BOOKSRUN_FTP_PORT:-}
BOOKSRUN_FTP_USER: ${BOOKSRUN_FTP_USER:-}
BOOKSRUN_FTP_REMOTE_PATH: ${BOOKSRUN_FTP_REMOTE_PATH:-}
BOOKSRUN_FTP_PASSWORD_FILE: /run/secrets/booksrun_ftp_password
services:
db:
@@ -99,6 +110,8 @@ services:
- ./secrets/${ENVIRONMENT:?ENVIRONMENT must be set}/db_password:/run/secrets/db_password:ro
- ./secrets/${ENVIRONMENT:?ENVIRONMENT must be set}/hardcover_api_token:/run/secrets/hardcover_api_token:ro
- ./secrets/${ENVIRONMENT:?ENVIRONMENT must be set}/helcim_api_token:/run/secrets/helcim_api_token:ro
- ./secrets/${ENVIRONMENT:?ENVIRONMENT must be set}/booksrun_api_key:/run/secrets/booksrun_api_key:ro
- ./secrets/${ENVIRONMENT:?ENVIRONMENT must be set}/booksrun_ftp_password:/run/secrets/booksrun_ftp_password:ro
healthcheck:
# No HTTP endpoint to hit directly — php-fpm speaks FastCGI on 9000,
# not HTTP, and this image has no `nc`. bash's /dev/tcp redirection
@@ -154,6 +167,8 @@ services:
- ./secrets/${ENVIRONMENT:?ENVIRONMENT must be set}/db_password:/run/secrets/db_password:ro
- ./secrets/${ENVIRONMENT:?ENVIRONMENT must be set}/hardcover_api_token:/run/secrets/hardcover_api_token:ro
- ./secrets/${ENVIRONMENT:?ENVIRONMENT must be set}/helcim_api_token:/run/secrets/helcim_api_token:ro
- ./secrets/${ENVIRONMENT:?ENVIRONMENT must be set}/booksrun_api_key:/run/secrets/booksrun_api_key:ro
- ./secrets/${ENVIRONMENT:?ENVIRONMENT must be set}/booksrun_ftp_password:/run/secrets/booksrun_ftp_password:ro
volumes:
db_data: