betting_combat.services.rounds_bootstrap
The one-command production bootstrap of strategy 4’s database (scripts/bootstrap_db.py):
create the data database, apply the three DDL files (fresh-install files: CREATE … IF NOT
EXISTS and CREATE OR REPLACE only, so applying them again changes nothing), seed the research
base set, verify it through the production loaders. Connections come only from
conf.Settings (the environment; production: Doppler) through the store’s own client
(conf.make_db_client, conf.make_pg for the maintenance database); DDL goes through this
module’s one explicit path (_unguarded), everything else through the store and the seed
services (upserts; no stored row is ever rewritten). Nothing is ever dropped. Schema: the
store’s (store._db.SCHEMA).
Refusals, all before anything is created or applied: a data database not named betting
(POSTGRES_DB; allow_other_db overrides), a data database holding user tables outside
the store’s schema, and a surface holding data other than the base set.
plan read-only: whether the data database exists, and per surface whether it is absent (to seed), equal to the research base set (unchanged), partly seeded (the missing part to seed) or holding OTHER data (refused: the whole run stops before writing anything)apply CREATE DATABASE (the data database only, when missing), the three DDL files, the seeds of every surface to seedverify every surface read back through ``services.rounds_inputs`` and compared exactly with the source files (the store known-answer tests' comparisons), and the row count of every tableThe research base set: the frozen inputs (data/ufc/parity/rounds/inputs, each file checked
against the manifest’s SHA-256) and the research’s hourly winner candles
(data/ufc/raw/kalshi_candles.json, not frozen: its SHA-256 is printed). cards limits the
Kalshi candles and trades to some cards (by the date code in the tickers; tests).
Classes
BaseSet
check_manifest
check_manifest() -> list[str]Every input file the manifest lists, against its SHA-256 (the problems).
hourly
hourly() -> dict[str, Any]json
json(path: Path) -> Anyminute_tickers
minute_tickers(series: str) -> list[str]on_cards
on_cards(ticker: str) -> booltapes
tapes() -> list[str]Report
say
say(line: str) -> NoneStep
Functions
apply_ddl
apply_ddl(db: Databases) -> list[str]The three idempotent DDL files, each on its database (the store’s schema only).
apply_seeds
apply_seeds(store: RoundsStore, base: BaseSet, steps: list[Step]) -> dict[str, int]Seed every surface planned ‘seed’ (refused plans never get here).
base_set
base_set(inputs: Path, candles: Path, cards: Iterable[str] | None = None) -> BaseSetcreate_database
create_database(maintenance: Pg, name: str) -> NoneCREATE DATABASE (the data database only; nothing is ever dropped).
database_exists
database_exists(maintenance: Pg, name: str) -> boolforeign_tables
foreign_tables(db: Databases) -> list[str]User tables of the data database outside the store’s schema (read-only).
plan
plan(store: RoundsStore, base: BaseSet) -> list[Step]What seeding would do, surface by surface (read-only).
run
run(settings: Settings, base: BaseSet, apply: bool, maintenance_db: str = 'postgres', allow_other_db: bool = False) -> ReportThe bootstrap (see the module doc). apply=False: the plan only, nothing written.
seed_pages
seed_pages(store: RoundsStore, raw: Path, keys: set[str]) -> intThe card-segment pages not stored yet (seed_card_segments’ rows, page by page).
seed_series_markets
seed_series_markets(store: RoundsStore, raw: Path, series: str) -> intverify
verify(store: RoundsStore, base: BaseSet) -> list[tuple[str, bool, str]]Every surface read back through the production loaders against the source files: (surface, equal, detail).