Skip to content

Schema-1 append: scale activity, game mix, permission shape, region, export - #7

Merged
rumblefrog merged 1 commit into
mainfrom
claude/loving-gauss-7yjbek
Oct 25, 2026
Merged

rumblefrog merged 1 commit into
mainfrom
claude/loving-gauss-7yjbek

Conversation

@rumblefrog

Copy link
Copy Markdown
Member

Closes #6.

Append-only additions to schema/1.lock.json. All new fields are .optional(), no schema bump, no existing position moves.

Lock changes

Dimension Before After Appended (in issue order)
blobs 11/20 12/20 panel.region (after extras, so blob12)
doubles 13/20 16/20 scale.bans_30d, scale.admins_active_30d, scale.ban_history_months
bits 27/53 39/53 scale.games.{tf,cstrike,csgo,garrysmod,left4dead2,other}, scale.perms.{web_groups,server_groups,overrides,immunity}, scale.web_bans_majority_30d, panel.exported_30d

Worker changes

  • src/schema.ts: panel.region (string), panel.exported_30d (bool), the three scale.* numbers, scale.web_bans_majority_30d, and nested scale.games / scale.perms objects (each .passthrough(), like the other sub-schemas).
  • src/ae.ts / src/features.ts: no changes. readPath and the bit-pack already walk multi-level dotted paths like scale.games.tf.
  • README: AE-layout block regenerated from the lock, request and curl examples, slot counts, bit/double headroom (39 bits, 4 doubles free). Also corrected the "extras (last blob)" note, since panel.region now sits behind it, and added a short privacy note that panel.region comes from the panel's config.timezone, never request.cf.

Tests

  • Each new slot round-trips to its lock-derived position from the canonical fixture (snapshot regenerated; new bitfield value checked by hand against the lock positions).
  • Each new bit set alone lands exactly at 2^lock.bits.indexOf(name).
  • An older payload (no new fields) yields null for the new doubles and panel.region, 0 for the new bits, and extras stays null.
  • The tail of each lock array equals the new slot list, in order (append-only guard).
  • The validator accepts nested scale.games / scale.perms and rejects wrong-typed leaves.

npm run typecheck, npm run lint, npm test (65 passing), prettier --check and npm run deploy:dry-run all pass locally.

Note for review

panel.region is validated as z.string(), not an enum of the six continent codes, to match the other blobs and the forward-compat optionality rule (a stricter enum would 400 a whole ping over one unexpected value). Happy to tighten it to z.enum([...]) if you'd rather reject anything else at the edge.

Panel collector changes are out of scope; the paired sourcebans-pp PR re-vendors the lock.


Generated by Claude Code

…ts to schema-1

Append-only additions to schema/1.lock.json, no schema bump:

- doubles (13 -> 16): scale.bans_30d, scale.admins_active_30d,
  scale.ban_history_months
- bits (27 -> 39): scale.games.{tf,cstrike,csgo,garrysmod,left4dead2,other},
  scale.perms.{web_groups,server_groups,overrides,immunity},
  scale.web_bans_majority_30d, panel.exported_30d
- blobs (11 -> 12): panel.region, appended after extras

src/schema.ts gains the matching optional Zod fields, including nested
scale.games / scale.perms objects. No mapper changes: readPath and the
bit-pack already walk multi-level dotted paths.

Tests pin each new slot to its lock-derived position, check that older
payloads yield null doubles / blobs and 0 bits with extras staying null,
and that wrong-typed nested leaves are rejected. README layout block,
request examples, slot counts and a panel.region privacy note updated.

Refs #6

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XsiwAF3BzPy1aMBEuQcGZe
@rumblefrog
rumblefrog merged commit d952bb9 into main Oct 25, 2026
1 check passed
rumblefrog added a commit to sbpp/sourcebans-pp that referenced this pull request Oct 25, 2026
… region and export signals (#1609)

sbpp/cf-analytics#7 appended these slots to schema-1 for
sbpp/cf-analytics#6. Mirror them in the vendored JSON Schema and add
the matching extractors so the parity test stays green:

- scale.bans_30d / admins_active_30d: 30-day counts from
  :prefix_bans.created and :prefix_admins.lastvisit.
- scale.ban_history_months: whole calendar months since the oldest
  ban (created = 0 legacy rows ignored); null without bans, so it is
  dropped from the wire body.
- scale.web_bans_majority_30d: more than half of last-30d bans have
  sid = 0.
- scale.games.*: tf / cstrike / csgo / garrysmod / left4dead2 / other
  over enabled servers' modfolders. Other folder names never leave
  the panel.
- scale.perms.*: any web group (type 1), server group, override, or
  admin with immunity > 0.
- panel.exported_30d: a Data Export success row in :prefix_log in the
  last 30 days.
- panel.region: continent code via the new Sbpp\Telemetry\Region,
  from config.timezone when it holds a zone name, else PHP's default
  timezone. Fresh 2.0 installs have no config.timezone and pre-2.0
  upgrades can hold a bare UTC offset there, so the fallback is what
  most installs will use. Never derived from the request.

Operator docs and the Features help text list the new fields.

Refs sbpp/cf-analytics#6


Claude-Session: https://claude.ai/code/session_01XsiwAF3BzPy1aMBEuQcGZe

Co-authored-by: Claude <noreply@anthropic.com>
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.

Schema-1 append: scale activity, game mix, permission shape, region, export

2 participants