feat(fairshare): add Set FairShare preferences skill - #115
Open
adaraPark wants to merge 1 commit into
Open
Conversation
Adds the first skill under a new `fairshare` category. The catalog had no coverage of FairShare attribution: the word "commission" appeared exactly once across all 42 skills, in a litigation-search table. The skill reads the four preferences from `/api/v2025-06/fairshare/settings`, explains what each option does and who it pays, collects choices through a `steps` picker, then writes the object back. Three non-obvious behaviors it encodes, verified against the Rails implementation: - Every PATCH field is optional, but the server assigns the whole StoreModel at once, so an omitted field resets to its default rather than retaining its value. Always GET, merge, PATCH all five fields. - `attribution_config` is retroactive: each order stores its own snapshot and that snapshot is overwritten with the company's current settings on recompute, so historical orders can re-credit. - `orphan_sponsor_config: random_rep` is not a blind lottery — the pool is the 10 reps with the most `url_visited` events in the last 30 days. `select_rep` with no rep id, and a deleted rep id, are both accepted by the API without complaint, so the skill resolves the rep before writing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
fairshare/fairshare-settings— the first skill under a newfairsharecategory.The catalog had no FairShare coverage. The word "commission" appears exactly once across the existing 42 skills, in a litigation-search table (
onboarding/onboarding-prefill), and the twofairsharementions inthemes/theme-refineandthemes/theme-revieware about the web-widget SDK's cart attributes, not rep attribution.What it does
Reads the four preferences from
GET /api/v2025-06/fairshare/settings, explains what each option does and who it pays, collects choices through astepspicker pre-selected to current values, confirms the irreversible ones, then PATCHes.It also explains the volume resolution order up front, since the preferences don't mean much without it: buyer's own rep → attributed rep → nearest rep-eligible sponsor → attributed rep as fallback → orphan policy.
Non-obvious behaviors it encodes
Verified against the Rails implementation rather than the OpenAPI surface:
optional, butUpdateActiondoescompany.update(fairshare: ...), assigning the whole StoreModel — so omitted keys become defaults, not their previous values.test/models/company_fairshare_test.rbproves it:update!(fairshare: {})reverts all four. The skill always GETs, merges, and sends all five fields.attribution_configis retroactive. Each order carries its own settings snapshot, andOrderAttributionService#ensure_order_fairshare_settings!overwrites it with the company's current settings whenever attribution is recomputed. Changing this can re-credit historical orders, so it gets an explicit confirmation.random_repis not a blind lottery.OrphanSponsorService#random_active_repsamples from the 10 reps with the mosturl_visitedevents in the last 30 days, cached hourly. The skill corrects that misreading explicitly, because the option name invites it.sponsor_repis not the direct sponsor. It walks a recursive genealogy CTE to the nearest rep-eligible ancestor; volume passes through customer interior nodes and customers never earn.select_repwith no rep id is accepted, as is a deleted rep id — there's no cross-field validation. The skill resolves the rep viaGET /api/v2025-06/reps/{id}before writing.It also warns that every step of the resolution chain is gated on
rep_eligible?, so with empty member-type permissions the chain collapses to the orphan policy and all four preferences appear inert.Scope
Sets and explains preferences. The "what it's worth" guidance describes mechanisms, not measurements — the skill explicitly declines to estimate how many of a given company's orders would change, and says so rather than guessing.
Validation
python3 scripts/validate_catalog.py→catalog validation passed: 43 skills, 7 workflows🤖 Generated with Claude Code