Skip to content

fix(events): keep three exported accounts behind every named organisation - #60

Merged
jm-rivera merged 1 commit into
devfrom
fix/export-fixes
Oct 24, 2026
Merged

jm-rivera merged 1 commit into
devfrom
fix/export-fixes

Conversation

@jm-rivera

Copy link
Copy Markdown
Contributor

account_daily named an organisation once its domain held 3 accounts, counting today's, while the view covers days through yesterday. A domain could then appear by name with 2 accounts in the export. Migration 0021_account_daily_before_today recreates the view so the threshold counts only accounts created before today (UTC), the accounts the export holds, and adds account_daily_source for the export's fault checks. db/account-export.ts fails on an empty user table or an empty webmail_domain, and replaces the BigQuery table with no rows when every account is from today, so a deleted account leaves the export.

The event export (db/event-export.ts) writes a NULLABLE export_rules column on every row: a digest of PROP_RULES, the path rules, EXPORT_SCHEMA, ROW_SHAPE_VERSION and an HMAC under EXPORT_ID_HMAC_KEY. Every day holding a row with another digest joins the run, so a rule change or a key rotation reaches every partition already loaded, and a day that fails is retried with the window on the next run. The first run after deploy reloads every day once. A day that fails keeps its partition while later days load, the run starts no new day after a 20-minute budget, and its error names the failed, short, and unreached days. Partition counts come from INFORMATION_SCHEMA.PARTITIONS (daily partitions only), and day reads page on (created_at, id). SHARE_MODES and the prompt intents are checked against their source unions, and a REQUIRED field added to EXPORT_SCHEMA fails to compile.

deploy/README.md gives the bounds (about 360 bytes an event, 0.5 MB on the busiest day so far against 512 MiB, and a 13.5 million row ceiling under the 1 GB billing cap), and db/connection.ts's comments describe the export Job's use of the runtime connection.

Testing: typecheck, lint and the db tests pass (155 against Postgres 18.4), and each new test fails without its change. IS DISTINCT FROM with a named parameter and the partition_id filter were run on prod BigQuery.

…tion

account_daily counts only accounts created before today (UTC), the accounts
the export holds, so a named domain always shows at least 3 of them. The
account export fails on an empty user table, replaces the table with no rows
when every account is from today, and fails on an empty webmail_domain.

Each exported event row carries export_rules, a digest of the export rules,
ROW_SHAPE_VERSION and an HMAC under the hashing key, and every day holding an
older digest reloads. A day that fails no longer blocks later days, the run
stops starting days after a 20-minute budget, and its error names the failed,
short, and unreached days.
@jm-rivera
jm-rivera merged commit 86d06a8 into dev Oct 24, 2026
1 check passed
@jm-rivera
jm-rivera deleted the fix/export-fixes branch October 24, 2026 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant