Award Join The Team to everybody, without a backfill

FeatureSecurityService
Shipped
September 7, 2026 at 5:05 AM UTC
Author
Kamo
Commit
7348f74

SecurityService owns the member, so it owns the achievement. It awards, reads, acknowledges and publishes; MediaService only relays. EVERY MEMBER GETS JOIN THE TEAM AND NOTHING HAD TO BE RUN. There are several paths that create a member and tens of thousands of members who predate the feature entirely; hooking creation covers the first group and a one-off script covers the second, and neither survives somebody adding a seventh creation path. So ensureBaseline is idempotent and called from BOTH — from MemberCreationService when a member is made, and from every read here. A member who predates the feature is awarded on the first request their browser makes, which is the same moment they could first have seen it. The award is BACKDATED to the day they joined. The achievement is a statement about the member; dating it to a deploy would make it a statement about us, and "held since March" is the sentence a trophy cabinet exists to be able to say. award() SETS the count rather than adding to it. A service that says "+1" is correct only if it is called exactly once per event forever, and the first retry or double-submit makes a member's record permanently wrong with nothing to compare it against. The publish is deferred to afterCommit, the way LeadEmailBackfillClient defers its back-fill and for a sharper reason: a frame sent from inside the awarding transaction congratulates a member on something a rollback then takes away, and they have already read it and pressed the button. Points arithmetic is read BEFORE any save, so it does not depend on when Hibernate happens to flush — a figure that is right in production and wrong under test is not a figure anyone can reason about. Repeat awards are caught by reading the recorded levels, not by catching the unique constraint: a violation marks the whole persistence context rollback-only, and the caller still has levels to write. Nothing here takes a member id from the caller. "Read somebody else's cabinet" is not a request that can be expressed, which is stronger than a right check because a later endpoint cannot forget to make it. The board sends memberId as a STRING. unique_rowid() is ~1.17e18, about 130x Number.MAX_SAFE_INTEGER, so a JSON number is rounded by JSON.parse before any browser code runs and every face on the board resolves to the wrong person. SCHEMA: **************** is applied by hand — ddl-auto is none and initializerservice is not deployed. Already applied to the cluster.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing