Handicap Audit
Score Posting Reminder
To:
Subject:
Round Note
Help & Support
Documentation for the Treesdale Score Posting Compliance Tool
Data Sources
SourceWhat It ContainsHow It Gets In
Golf Genius RosterMember number, first & last name, GHIN number — the authoritative link between ClubCorp members and GHINManual upload on dashboard
GHIN Active RosterGHIN number, golfer name, H.I., status, email, genderAutomated — GHIN emails report, processed daily at 8am ET (scores) and Monday 8am ET (roster)
Scores Posted ReportGHIN number, date played, date posted, AGS, holes, course, differentialAutomated — same GHIN email pipeline
ClubCorp Tee SheetsPer-player: ClubCorp ID, name, member code, holes, cart type, member type, player categoryManual upload — save .htm from ClubCorp Tee Times, upload per course per day
How Matching Works

The tool connects tee sheet players to roster members, then checks whether their scores were posted. This happens in three steps.

Step 1 — Identify the Player

Every tee sheet entry includes a member number (e.g., S0262). The system looks up that number in the Golf Genius Master Roster:

ScenarioWhat Happens
Only one member on that codeThat's the member. Done — no name matching needed.
Multiple members on that codeCheck if the player's ClubCorp ID (a unique per-person identifier from the tee sheet) has already been stored from a previous match. If found, match confirmed.
No stored ClubCorp ID yetFall back to name matching: filter by last name, then score by first name using exact match, a 100+ nickname map (Bob↔Robert, Tom↔Thomas, Mike↔Michael, etc.), and first-3-character comparison. Clear winner = matched.
After a successful matchThe player's ClubCorp ID is saved to their roster record. Next time they play, the match is instant — no name matching required.

Step 2 — Check Score Posting

Once the player is identified, the system uses their GHIN number from the roster to look up posted Treesdale scores. Only Treesdale-course scores count — away-play scores are ignored. Matching runs in three passes:

Pass A — Exact date (4 tiers, best match wins)

TierMatch CriteriaNote
1Same date + same course + same holesBest possible match
2Same date + same holes (course differs)Holes take priority over course
3Same date + same course (holes differ)Holes flagged as ⚠ mismatch
4Same date, any Treesdale scoreLast resort; holes flagged ⚠

Pass B — Fuzzy date (1–3 days after tee date)

For rounds still missing after Pass A, the system searches for a Treesdale score whose date_played is 1–3 days after the tee sheet date (same course required when known). This catches scores entered with a next-day or delayed date. The window is forward-only — a score cannot predate the round. Fuzzy-matched rounds are flagged with a ⚠ warning and the actual score date shown on hover.

Pass C — Family member fallback

If a round is still missing after Passes A & B, the system checks whether a family member (sharing the same member number) posted a score for that date. Family members who have their own tee sheet entry on the same date are excluded — their score is reserved for their own slot. When a family score is used, the booked name appears struck through on the tee sheet with the actual player's name shown below, and the audit flags the round as ✓ Family.

Each score can only be consumed once across all three passes. If a member played 2 rounds but posted 1 score, the best-matching round shows Posted and the other shows Missing.

Step 3 — Tee Sheet Display

Dot ColorMeaning
GreenMatched member — score posted for this date
RedMatched member — score missing for this date
GoldRound credited to a family member's posted score
GreyNot matched — guest, family member without GHIN, social member, or unresolved
Matching Scenarios — Worked Examples

Concrete examples of how a tee-sheet entry is resolved to a member and how a score is matched. "Code" = ClubCorp member code; "CC ID" = the unique per-person ClubCorp ID.

Identifying the player

SituationWhat happensResult
Code has one GHIN holder; CC ID already on fileThe stored CC ID matches instantly — no name comparison needed.Matched (Tier 1)
Family code "S0262" — booked as "Bob Smith"Two members share the code: Robert and Susan Smith. First name "Bob" maps to "Robert" via the nickname table.Matched → Robert
Same code — booked as "Susan Smith"First-name score favors Susan over Robert.Matched → Susan
Nickname/short forms (Bob/Robert, Mike/Michael, Tom/Thomas, Chris/Christopher)A 100+ entry nickname map plus first-3-character comparison resolves the first name.Matched
Matched member's CC ID on file differs from the entry's CC IDThe entry belongs to a different person on the shared code (e.g. a dependent) — the match is rejected to prevent mis-attribution.Not matched (grey)
Two members on a code are genuinely indistinguishable (e.g. two "Mike Davis")No first-name winner — surfaced for a human to confirm.Needs Review
Member flagged affiliated with another clubExcluded from Treesdale compliance entirely.Affiliated (grey)
Associate / play-away code (e.g. 12345-67890)Not a Treesdale member — skipped.Play Away
Guest placeholder CC ID (1–4)Reserved guest IDs — never matched to a member.Guest (grey)

Matching the score

SituationWhat happensResult
Played Grove/Lakes 18; posted Treesdale G/L 18 same dayExact match on date + course + holes.Posted
Played a Treesdale round; only posted score is an away courseAway-play scores never count toward Treesdale compliance.Missing
Round on the 1st; score's date_played is the 3rdFuzzy pass matches a score 1–3 days after the round (forward-only — a score can't predate the round).Posted ⚠
Score's date is 2 days before the roundForward-only window rejects it.Missing
Same course & date, but booked 18 / posted 9Matched, with a holes-mismatch warning on hover.Posted ⚠
Played 2 rounds that day, posted 1 scoreEach score is consumed once. The best-matching round gets it.1 Posted, 1 Missing
Parent booked but didn't post; a family member posted that dayFamily fallback credits the round to the family member who has an unused score within 0–3 days (and isn't on the tee sheet themselves).✓ Family
Member played alone with no posted scoreSolo rounds aren't required by the USGA. (A postable partner round claims any score first.)Non-Postable
Player Types & Badges

The tee sheet shows ALL players. Each gets a badge. Only entry_type=member + player_category=Golf are audited for compliance.

BadgeTypeAudited?
MMember (Golf)Yes — tracked for compliance
GGuest of MemberNo
UUnaccompanied GuestNo
AAssociate MemberNo
AAAccess AdvantageNo
PPlay Away PremierNo
EEmployeeNo
Automation Pipeline
ScheduleWhatHow
Daily 8am ETScores Posted ReportGHIN emails .xlsx → Gmail → Edge Function. Only inserts scores with posted_date = yesterday or day before. Quick edit check on last 7 days.
Monday 8am ETGHIN Active RosterGHIN emails .xlsx → Gmail → Edge Function. Full upsert by GHIN number — updates status, H.I., email.
After tee sheet uploadClubCorp ID capturecaptureClubcorpIds() links tee sheet ClubCorp IDs to Golf Genius members for Tier 1 matching.
After GG uploadDisplay name syncSyncs display_name and display_email from Golf Genius to the GHIN roster for canonical name/email display.
Audit Tool

Select a date range (up to 1 month). The audit loads tee sheet entries, runs the full 3-pass matching pipeline (exact date → fuzzy → family fallback), cross-references GHIN scores, and groups results by member. Rounds outside a member's active membership window are excluded. Date pickers only allow today or earlier.

Audit columns — By Member view

ColumnMeaning
PlayedTotal tee sheet entries for the member in the selected period
PostableRounds the member was responsible for posting (Played minus Non-Postable)
PostedOf those postable rounds, how many have a matched GHIN score
Non-PostRounds not counted toward compliance: solo rounds (played alone, no score required by the system) and admin-exempted rounds (checkbox in the round detail). Played = Postable + Non-Post.
MissingPostable − Posted. These are the rounds that still need action.

Member status badges

StatusMeaning
CompliantAll postable rounds have a matched score
EmailedAll missing rounds have had a reminder email sent
PartialSome missing rounds emailed, some not yet contacted
MissingHas unposted rounds, no reminder emails sent yet

Round detail (click a member row to expand)

Each round shows date, course, time, holes played (actual posted holes, not booking holes), score (AGS), differential, post date, and status:

Round StatusMeaning
PostedScore matched — hover for AGS, differential, and post date
Posted ⚠Score matched via fuzzy date or with a holes mismatch — hover for details
✓ FamilyScore matched to a family member who played the round — hover to see who
Emailed & PostedScore posted on or after the day a reminder was sent
⚠ Emailed in ErrorA reminder was sent even though the score had already been posted on an earlier day — usually because the Scores Posted Report hadn't updated yet. Surfaced here and on the Email History page so these can be tracked.
Missing & EmailedStill no score, but a reminder was sent
MissingNo score found, no email sent
Non-PostableSolo round or admin-exempted — excluded from compliance math

The Non-Postable checkbox in each round row lets admins mark a round exempt (e.g. a member played as a guest on their own account, or a round that shouldn't count). Checking it removes the round from Postable and Missing counts immediately and persists to the database.

Known Edge Cases
IssueHow It's Handled
Apostrophes in names (O'Connor, L'Herbier)nlk() strips apostrophes for all lookups
Titles (Dr., Mr., Mrs.) in GHIN namesnlk() strips all titles before matching
Suffixes (Jr., Sr., III, IV) in namesnlk() strips suffixes
Professional designations (CPA, MD, DA)nlk() strips them
Family members sharing a member numberRoster Step 1 disambiguates by ClubCorp ID first, then first name + 100+ nickname map. Score Pass C then checks family scores as a last resort for any round still missing.
Member joined or left mid-periodRounds played before a member's active date — or on/after their inactive date — are excluded from compliance (not counted as missing)
GG members with NULL member_number (156)Tier 4 matches by name → GHIN roster as fallback
Multiple rounds on same date4-tier priority matching by course + holes; each score consumed only once across all passes.
Score entered with wrong date (off by 1–3 days)Fuzzy pass searches for a Treesdale score 1–3 days after the tee sheet date (forward-only — a score cannot predate a round). Matched rounds are flagged ⚠ with the actual score date shown on hover.
CC ID ≠ Member# (membership transfers)Flagged as "Needs Review" — excluded from compliance until manually confirmed
Guest placeholder ClubCorp IDs (1-4)Skipped — never matched
Play-away codes (XXXXX-XXXXX)Skipped — not Treesdale members