wiq-cli 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/docs/deferred.md +8 -4
- data/docs/wiq_api_notes.md +39 -10
- data/lib/wiq/cli.rb +3 -0
- data/lib/wiq/commands/events.rb +13 -3
- data/lib/wiq/commands/locations.rb +64 -0
- data/lib/wiq/commands/metrics.rb +16 -2
- data/lib/wiq/commands/paid_sessions.rb +6 -0
- data/lib/wiq/commands/reports.rb +78 -19
- data/lib/wiq/commands/rosters.rb +8 -0
- data/lib/wiq/commands/wrestlers.rb +8 -0
- data/lib/wiq/version.rb +1 -1
- data/lib/wiq.rb +1 -0
- data/share/skills/wiq/SKILL.md +72 -5
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bffdea54163c5b95a5cab8b219d3e5cb3a898a059d7edce13afa8ae02928b27a
|
|
4
|
+
data.tar.gz: 0f9e49529c6bc9fb37b75761e581d1de90a186107242a6c3092fcca55687f9ba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 57f4ccba1f18ca17207739d051e94fcfb1b52b712c2d87e97fc64951acd4041d37a69f6d89d262dfde73cc44d278549d6ac9af02b67a572e3dd549dd2c58cd95
|
|
7
|
+
data.tar.gz: a317f13e135ab5b7a20f24b7f0c8a6640cbf84afc6a0a3e8d38d9d6483a537c302289f479b1cac0d454ca9c10485ebbcf453804decf4cdf02dbd73b822b0b933
|
data/docs/deferred.md
CHANGED
|
@@ -144,10 +144,14 @@ Last updated: 2026-05-12 (after L1 ships).
|
|
|
144
144
|
- **Echo `request_id`** in the response body or `X-Request-ID` header,
|
|
145
145
|
for support correlation. Today the CLI can't give a customer a request
|
|
146
146
|
ID to ship to support.
|
|
147
|
-
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
147
|
+
- ~~**Real location/site filter on events.**~~ — SHIPPED (June 2026,
|
|
148
|
+
wre-506). The backend grew a structured Location model. The CLI now
|
|
149
|
+
exposes `wiq locations list|show` plus `--location` flags on
|
|
150
|
+
`events list` (repeatable → `location_ids[]`), `rosters list`
|
|
151
|
+
(`q[location_id_eq]`), `paid_sessions list`, `wrestlers list`,
|
|
152
|
+
`metrics show`, and `reports run` (args.location_id, honored by 13
|
|
153
|
+
report types). The legacy free-text `Event.location` remains for old
|
|
154
|
+
rows; serialized `location` is the display form.
|
|
151
155
|
- **Subdomain discovery flow for `wiq auth login`.** PAT settings URL
|
|
152
156
|
lives at `<team-subdomain>.wrestlingiq.com/settings/personal_access_tokens`.
|
|
153
157
|
If a customer doesn't know their subdomain, the CLI can't deep-link
|
data/docs/wiq_api_notes.md
CHANGED
|
@@ -246,6 +246,29 @@ file with the WIQ team.
|
|
|
246
246
|
|
|
247
247
|
- `POST /api/v1/reports`
|
|
248
248
|
- Body: `{ "report": { "type": "<ReportClass>", "version": "v1"|"vrow", "name": "...", "start_at": "YYYY-MM-DD", "end_at": "YYYY-MM-DD", "args": { ... } } }`
|
|
249
|
+
- **`version` — v1 vs vrow.** `:version` is in the controller permit
|
|
250
|
+
list (`reports_controller.rb#report_params`). Despite both being
|
|
251
|
+
accepted everywhere, version only changes output for three reports —
|
|
252
|
+
`RosterReport`, `UsawReport`, `PaidSessionAccountingReport` — which
|
|
253
|
+
branch in `generate_ver_result!` (`v1?` → structured JSON objects,
|
|
254
|
+
`vrow?` → row/CSV with a leading header row). All three implement
|
|
255
|
+
both; no report is v1-only. Every other report overrides
|
|
256
|
+
`generate_ver_result!` and emits rows regardless of version. vrow is
|
|
257
|
+
the de facto standard, so the CLI defaults to it (uniform row shape
|
|
258
|
+
across all reports) and exposes the legacy structured shape via
|
|
259
|
+
`wiq reports run … --v1`.
|
|
260
|
+
- **`RosterReport` "Added to roster at" lives only in vrow.** The vrow
|
|
261
|
+
path calls `get_wrestlers_and_roster(include_roster_memberships: true)`
|
|
262
|
+
(`report.rb`), which `.select`s
|
|
263
|
+
`roster_memberships.created_at as added_to_roster_at` and emits it as
|
|
264
|
+
the `"Added to roster at"` column. The v1 path renders wrestlers via
|
|
265
|
+
`_wrestler_profile.json.jbuilder`, which has no such field. The join
|
|
266
|
+
only happens for a specific roster (`roster_id > 0`); `roster_id: 0`
|
|
267
|
+
("all wrestlers") takes the else branch and the value is nil — a
|
|
268
|
+
wrestler can be on multiple rosters, so the join date is per-roster.
|
|
269
|
+
The roster index/show jbuilder (`_roster.json.jbuilder`) exposes only
|
|
270
|
+
`stats.roster_memberships_count`, never per-membership timestamps, so
|
|
271
|
+
vrow RosterReport is the sole API path to this data.
|
|
249
272
|
- Permitted `args` keys (`reports_controller.rb#report_params`):
|
|
250
273
|
`paid_session_id, roster_id, fundraiser_id, online_store_id, event_id,
|
|
251
274
|
include_archived_roster_tags, append_property_ids[]`.
|
|
@@ -445,13 +468,16 @@ Other registration surface:
|
|
|
445
468
|
- `expand=event_invites,event_bookings,private_lessons` — comma-separated
|
|
446
469
|
CSV; pulls in nested data on the events index/show.
|
|
447
470
|
- `Event.ransackable_attributes` allows
|
|
448
|
-
`id, name, start_at, end_at, event_type, paid_session_id`.
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
471
|
+
`id, name, start_at, end_at, event_type, paid_session_id`. The
|
|
472
|
+
free-text `location` column is still not ransackable, but the
|
|
473
|
+
structured location filter shipped (June 2026): pass `location_ids[]`
|
|
474
|
+
(repeatable, dedicated param handled in `apply_event_filters`, not
|
|
475
|
+
Ransack) to filter on the event's `location_id`. Events with no
|
|
476
|
+
`location_id` are excluded from a filtered listing. The serialized
|
|
477
|
+
`location` field is now `Event#display_location` — the structured
|
|
478
|
+
Location's name when set, else the legacy free text — and `location_id`
|
|
479
|
+
is serialized alongside it. The CLI exposes this as
|
|
480
|
+
`wiq events list --location <id> [<id>...]`.
|
|
455
481
|
- Soft deletes: events use `acts_as_paranoid`; the index calls
|
|
456
482
|
`.without_deleted`. No "include deleted" param exposed.
|
|
457
483
|
- `POST /api/v1/events` — recurring practice creation:
|
|
@@ -619,9 +645,12 @@ PaidSession-overlap convention proves load-bearing for many customers.
|
|
|
619
645
|
demand. Until then, jbuilders are the source of truth.
|
|
620
646
|
2. `request_id` echoed in response body and/or `X-Request-ID` header for
|
|
621
647
|
support correlation.
|
|
622
|
-
3. Real location/site filter on `GET /api/v1/events
|
|
623
|
-
|
|
624
|
-
|
|
648
|
+
3. ~~Real location/site filter on `GET /api/v1/events`~~ — SHIPPED
|
|
649
|
+
(June 2026, wre-506). Structured Location model + `location_ids[]` on
|
|
650
|
+
events, `location_id` on paid_sessions/wrestlers/metrics/reports,
|
|
651
|
+
`q[location_id_eq]` on rosters, and a `GET /api/v1/locations`
|
|
652
|
+
resource. All exposed in the CLI via `wiq locations` and `--location`
|
|
653
|
+
flags.
|
|
625
654
|
4. Subdomain discovery for `wiq auth login`. The PAT settings URL lives at
|
|
626
655
|
`<team-subdomain>.wrestlingiq.com/settings/personal_access_tokens`; if
|
|
627
656
|
the customer doesn't know their subdomain, the CLI can't deep-link
|
data/lib/wiq/cli.rb
CHANGED
|
@@ -65,6 +65,9 @@ module Wiq
|
|
|
65
65
|
desc "rosters SUBCOMMAND", "Rosters (list, show)"
|
|
66
66
|
subcommand "rosters", Wiq::Commands::Rosters
|
|
67
67
|
|
|
68
|
+
desc "locations SUBCOMMAND", "Team locations / sites — ID discovery for --location flags (list, show)"
|
|
69
|
+
subcommand "locations", Wiq::Commands::Locations
|
|
70
|
+
|
|
68
71
|
desc "prospects SUBCOMMAND", "Prospect pipeline — individual kids (list, show, summary)"
|
|
69
72
|
subcommand "prospects", Wiq::Commands::Prospects
|
|
70
73
|
|
data/lib/wiq/commands/events.rb
CHANGED
|
@@ -25,18 +25,25 @@ module Wiq
|
|
|
25
25
|
--event-type One of `wiq events types` (practice, dual_meet, ...)
|
|
26
26
|
--roster One or more roster ids (the API joins through
|
|
27
27
|
roster_events)
|
|
28
|
+
--location One or more location ids (structured Location
|
|
29
|
+
records; discover via `wiq locations list`)
|
|
28
30
|
--expand CSV of event_invites,event_bookings,private_lessons.
|
|
29
31
|
Drops nested data into each event row.
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
Location caveat: --location matches the event's own structured
|
|
34
|
+
location_id. Events with NO location set are excluded from a
|
|
35
|
+
filtered listing — they only appear when you don't filter. The
|
|
36
|
+
legacy free-text `location` field still exists on old events; the
|
|
37
|
+
serialized `location` value is the display form (structured record
|
|
38
|
+
when set, else the free text).
|
|
34
39
|
|
|
35
40
|
Use --all to walk every page; default is page 1, per_page=100.
|
|
36
41
|
DESC
|
|
37
42
|
method_option :start, type: :string, required: true, desc: "YYYY-MM-DD (team timezone)"
|
|
38
43
|
method_option :end, type: :string, required: true, desc: "YYYY-MM-DD (team timezone)"
|
|
39
44
|
method_option :roster, type: :array, desc: "One or more roster ids"
|
|
45
|
+
method_option :location, type: :array,
|
|
46
|
+
desc: "One or more location ids (events with no location are excluded)"
|
|
40
47
|
method_option :event_type, type: :string, enum: %w[practice dual_meet tournament scramble private_lesson other],
|
|
41
48
|
desc: "Filter to one event_type (see `wiq events types`)"
|
|
42
49
|
method_option :expand, type: :string,
|
|
@@ -53,6 +60,9 @@ module Wiq
|
|
|
53
60
|
if options[:roster]
|
|
54
61
|
options[:roster].each { |rid| (params["roster_ids[]"] ||= []) << rid }
|
|
55
62
|
end
|
|
63
|
+
if options[:location]
|
|
64
|
+
options[:location].each { |lid| (params["location_ids[]"] ||= []) << lid }
|
|
65
|
+
end
|
|
56
66
|
|
|
57
67
|
records, total = fetch_index("/api/v1/events", params, key: "events")
|
|
58
68
|
render_index(
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Wiq
|
|
4
|
+
module Commands
|
|
5
|
+
class Locations < Base
|
|
6
|
+
desc "list", "List the team's structured locations (sites/gyms)"
|
|
7
|
+
long_desc <<~DESC
|
|
8
|
+
Locations are WIQ's structured multi-site concept — a named place
|
|
9
|
+
(with optional street address) that rosters, events, paid sessions,
|
|
10
|
+
wrestlers, metrics, and reports can be scoped to. Single-site clubs
|
|
11
|
+
typically have zero or one; multi-site clubs use them to slice
|
|
12
|
+
everything per gym.
|
|
13
|
+
|
|
14
|
+
Archived locations are hidden by default; pass --include-archived
|
|
15
|
+
to see them. Ordered by name server-side.
|
|
16
|
+
|
|
17
|
+
This is the ID-discovery surface for every --location flag in the
|
|
18
|
+
CLI:
|
|
19
|
+
wiq rosters list --location <id>
|
|
20
|
+
wiq events list --location <id> [...more ids]
|
|
21
|
+
wiq wrestlers list --location <id>
|
|
22
|
+
wiq paid_sessions list --location <id>
|
|
23
|
+
wiq metrics show <name> --location <id>
|
|
24
|
+
wiq reports run <Type> --location <id>
|
|
25
|
+
DESC
|
|
26
|
+
method_option :include_archived, type: :boolean, default: false,
|
|
27
|
+
desc: "Include archived locations"
|
|
28
|
+
method_option :all, type: :boolean, default: false
|
|
29
|
+
def list
|
|
30
|
+
params = { "per_page" => 100 }
|
|
31
|
+
params["include_archived"] = true if options[:include_archived]
|
|
32
|
+
|
|
33
|
+
records, total = fetch_index("/api/v1/locations", params, key: "locations")
|
|
34
|
+
render_index(
|
|
35
|
+
records, total: total,
|
|
36
|
+
summary: "Listed #{records.size} locations#{options[:include_archived] ? " (including archived)" : ""}.",
|
|
37
|
+
breadcrumbs: [
|
|
38
|
+
{ "cmd" => "wiq locations show <id>", "description" => "Inspect a single location" },
|
|
39
|
+
{ "cmd" => "wiq rosters list --location <id>", "description" => "Rosters at a location" },
|
|
40
|
+
{ "cmd" => "wiq metrics show mrr --location <id>",
|
|
41
|
+
"description" => "Finance metrics scoped to a location (admin only)" }
|
|
42
|
+
]
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
desc "show ID", "Fetch a single location"
|
|
47
|
+
long_desc <<~DESC
|
|
48
|
+
Full location payload: id, name, address_line1, address_line2,
|
|
49
|
+
city, state, postal_code, country, archived.
|
|
50
|
+
DESC
|
|
51
|
+
def show(id)
|
|
52
|
+
location = client.get("/api/v1/locations/#{id}")
|
|
53
|
+
render(location,
|
|
54
|
+
summary: "Location #{location["id"]} — #{location["name"]}",
|
|
55
|
+
breadcrumbs: [
|
|
56
|
+
{ "cmd" => "wiq rosters list --location #{location["id"]}",
|
|
57
|
+
"description" => "Rosters at this location" },
|
|
58
|
+
{ "cmd" => "wiq wrestlers list --location #{location["id"]}",
|
|
59
|
+
"description" => "Wrestlers on any roster at this location" }
|
|
60
|
+
])
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
data/lib/wiq/commands/metrics.rb
CHANGED
|
@@ -62,6 +62,13 @@ module Wiq
|
|
|
62
62
|
Intervals: hourly, daily, weekly, monthly. Invalid values are
|
|
63
63
|
silently coerced to `daily` server-side.
|
|
64
64
|
|
|
65
|
+
--location <id> scopes every metric to one structured location
|
|
66
|
+
(discover ids via `wiq locations list`). CAUTION: the server
|
|
67
|
+
validates the id against the team's own locations and silently
|
|
68
|
+
falls back to ALL locations when it doesn't match — a typo'd or
|
|
69
|
+
foreign id returns team-wide numbers, not an error. The CLI echoes
|
|
70
|
+
the requested location in `meta` so you can sanity-check.
|
|
71
|
+
|
|
65
72
|
Currency metrics return integer cents (divide by 100 for dollars).
|
|
66
73
|
Non-currency metrics return raw counts.
|
|
67
74
|
DESC
|
|
@@ -70,6 +77,8 @@ module Wiq
|
|
|
70
77
|
enum: VALID_INTERVALS, desc: "interval_group"
|
|
71
78
|
method_option :start_date, type: :string, desc: "Required if --range=custom"
|
|
72
79
|
method_option :end_date, type: :string, desc: "Required if --range=custom"
|
|
80
|
+
method_option :location, type: :numeric,
|
|
81
|
+
desc: "Scope to one location id (unknown ids silently mean ALL locations)"
|
|
73
82
|
method_option :no_comparison, type: :boolean, default: false,
|
|
74
83
|
desc: "Drop comparison_series/comparison_total from output"
|
|
75
84
|
def show(name)
|
|
@@ -91,6 +100,7 @@ module Wiq
|
|
|
91
100
|
params["start_date"] = options[:start_date]
|
|
92
101
|
params["end_date"] = options[:end_date]
|
|
93
102
|
end
|
|
103
|
+
params["location_id"] = options[:location] if options[:location]
|
|
94
104
|
|
|
95
105
|
payload = client.get("/api/v1/metrics/#{name}", params)
|
|
96
106
|
metrics = payload["metrics"] || {}
|
|
@@ -106,9 +116,13 @@ module Wiq
|
|
|
106
116
|
data["comparison_total"] = metrics["comparison_total"]
|
|
107
117
|
end
|
|
108
118
|
|
|
119
|
+
meta = { "currency_unit" => CURRENCY_METRICS.include?(name) ? "cents" : "count" }
|
|
120
|
+
meta["location_id"] = options[:location] if options[:location]
|
|
121
|
+
|
|
109
122
|
render(data,
|
|
110
|
-
summary: "metric=#{name} range=#{options[:range]} interval=#{options[:interval]}"
|
|
111
|
-
|
|
123
|
+
summary: "metric=#{name} range=#{options[:range]} interval=#{options[:interval]}" \
|
|
124
|
+
"#{options[:location] ? " location=#{options[:location]}" : ""}",
|
|
125
|
+
meta: meta,
|
|
112
126
|
breadcrumbs: [
|
|
113
127
|
{ "cmd" => "wiq metrics list", "description" => "See all supported metrics" }
|
|
114
128
|
])
|
|
@@ -20,6 +20,10 @@ module Wiq
|
|
|
20
20
|
recurring_registerable, not_recurring, not_recurring_with_archived,
|
|
21
21
|
not_archived, dropin, trial, trial_or_dropin
|
|
22
22
|
|
|
23
|
+
--location <id> filters server-side to sessions stamped with that
|
|
24
|
+
structured location (discover ids via `wiq locations list`).
|
|
25
|
+
Sessions with no location are excluded when the filter is on.
|
|
26
|
+
|
|
23
27
|
--season filters CLI-side to sessions whose [start_at, end_at] window
|
|
24
28
|
overlaps the given calendar year. Pair with --all to get an exhaustive
|
|
25
29
|
list.
|
|
@@ -30,11 +34,13 @@ module Wiq
|
|
|
30
34
|
you usually don't need a follow-up call.
|
|
31
35
|
DESC
|
|
32
36
|
method_option :type, type: :string, enum: PRESET_TYPES, desc: "Preset scope filter"
|
|
37
|
+
method_option :location, type: :numeric, desc: "Filter to sessions at one location id"
|
|
33
38
|
method_option :season, type: :numeric, desc: "Filter to sessions overlapping calendar year"
|
|
34
39
|
method_option :all, type: :boolean, default: false
|
|
35
40
|
def list
|
|
36
41
|
params = { "per_page" => 50 }
|
|
37
42
|
params[:type] = options[:type] if options[:type]
|
|
43
|
+
params["location_id"] = options[:location] if options[:location]
|
|
38
44
|
|
|
39
45
|
records, total = fetch_index("/api/v1/paid_sessions", params, key: "paid_sessions")
|
|
40
46
|
|
data/lib/wiq/commands/reports.rb
CHANGED
|
@@ -26,7 +26,7 @@ module Wiq
|
|
|
26
26
|
TYPES = {
|
|
27
27
|
# ── Roster tab ───────────────────────────────────────────────
|
|
28
28
|
"RosterReport" => {
|
|
29
|
-
args: %w[roster_id append_property_ids include_archived_roster_tags],
|
|
29
|
+
args: %w[roster_id location_id append_property_ids include_archived_roster_tags],
|
|
30
30
|
dates: :optional,
|
|
31
31
|
desc: "Roster snapshot — name, weight class, academic class, age",
|
|
32
32
|
recommended: true,
|
|
@@ -36,8 +36,17 @@ module Wiq
|
|
|
36
36
|
"--visibility private if admin) to surface intake data as " \
|
|
37
37
|
"extra columns. Skip questions with a deleted_at — they're " \
|
|
38
38
|
"still in the index payload but won't render. roster_id=0 " \
|
|
39
|
-
"means \"all rosters\". Each appended question becomes a column."
|
|
40
|
-
|
|
39
|
+
"means \"all rosters\". Each appended question becomes a column. " \
|
|
40
|
+
"The default row/CSV shape (web Download) carries the \"Added " \
|
|
41
|
+
"to roster at\" column (roster_memberships.created_at — when the " \
|
|
42
|
+
"wrestler landed on the roster, NOT their registration date), " \
|
|
43
|
+
"populated only for a specific --roster <id> (id > 0), not " \
|
|
44
|
+
"--roster 0. With --location <id> instead, the report scopes to " \
|
|
45
|
+
"wrestlers on any roster at that location (one row each) and " \
|
|
46
|
+
"\"Added to roster at\" becomes their EARLIEST membership across " \
|
|
47
|
+
"that location's rosters. --v1 returns fuller per-wrestler " \
|
|
48
|
+
"objects but drops that column.",
|
|
49
|
+
example: "wiq reports run RosterReport --roster 42"
|
|
41
50
|
},
|
|
42
51
|
"FullExportWrestlerReport" => {
|
|
43
52
|
args: %w[],
|
|
@@ -61,52 +70,52 @@ module Wiq
|
|
|
61
70
|
|
|
62
71
|
# ── USAW / AAU tab ───────────────────────────────────────────
|
|
63
72
|
"UsawReport" => {
|
|
64
|
-
args: %w[roster_id],
|
|
73
|
+
args: %w[roster_id location_id],
|
|
65
74
|
dates: :optional,
|
|
66
75
|
desc: "All USA Wrestling card info on file, one row per wrestler",
|
|
67
76
|
recommended: true,
|
|
68
77
|
notes: "UI hides this tab when USAW collection is off (team setting)."
|
|
69
78
|
},
|
|
70
79
|
"UsawExpiredReport" => {
|
|
71
|
-
args: %w[roster_id],
|
|
80
|
+
args: %w[roster_id location_id],
|
|
72
81
|
dates: :optional,
|
|
73
82
|
desc: "Wrestlers missing or with expired USAW memberships",
|
|
74
83
|
notes: "Output is also a bulk-purchase upload format for USAW's system."
|
|
75
84
|
},
|
|
76
85
|
"UsawExportReport" => {
|
|
77
|
-
args: %w[roster_id paid_session_id],
|
|
86
|
+
args: %w[roster_id location_id paid_session_id],
|
|
78
87
|
dates: :optional,
|
|
79
88
|
desc: "USAW bulk-purchase upload format",
|
|
80
89
|
notes: "Only report that accepts paid_session_id=0 to mean " \
|
|
81
90
|
"\"all sessions\"."
|
|
82
91
|
},
|
|
83
92
|
"AauReport" => {
|
|
84
|
-
args: %w[roster_id],
|
|
93
|
+
args: %w[roster_id location_id],
|
|
85
94
|
dates: :optional,
|
|
86
95
|
desc: "All AAU card info on file, one row per wrestler",
|
|
87
96
|
recommended: true,
|
|
88
97
|
notes: "UI hides this tab when AAU collection is off (team setting)."
|
|
89
98
|
},
|
|
90
99
|
"AauExpiredReport" => {
|
|
91
|
-
args: %w[roster_id],
|
|
100
|
+
args: %w[roster_id location_id],
|
|
92
101
|
dates: :optional,
|
|
93
102
|
desc: "Wrestlers missing or with expired AAU memberships"
|
|
94
103
|
},
|
|
95
104
|
"AauExportReport" => {
|
|
96
|
-
args: %w[roster_id],
|
|
105
|
+
args: %w[roster_id location_id],
|
|
97
106
|
dates: :optional,
|
|
98
107
|
desc: "AAU bulk-purchase upload format"
|
|
99
108
|
},
|
|
100
109
|
|
|
101
110
|
# ── Stats tab ────────────────────────────────────────────────
|
|
102
111
|
"WinLossReport" => {
|
|
103
|
-
args: %w[roster_id],
|
|
112
|
+
args: %w[roster_id location_id],
|
|
104
113
|
dates: :required,
|
|
105
114
|
desc: "Wins and losses per wrestler",
|
|
106
115
|
recommended: true
|
|
107
116
|
},
|
|
108
117
|
"RosterStatsReport" => {
|
|
109
|
-
args: %w[roster_id],
|
|
118
|
+
args: %w[roster_id location_id],
|
|
110
119
|
dates: :required,
|
|
111
120
|
desc: "Wrestling stats per wrestler (takedowns, nearfall, etc.)",
|
|
112
121
|
recommended: true
|
|
@@ -127,8 +136,10 @@ module Wiq
|
|
|
127
136
|
recommended: true,
|
|
128
137
|
notes: "One row per wrestler over the date range — totals across all " \
|
|
129
138
|
"their check-ins in the window. If you want one row per " \
|
|
130
|
-
"check-in event use CheckInFeedReport.
|
|
131
|
-
"
|
|
139
|
+
"check-in event use CheckInFeedReport. Always team-wide: the " \
|
|
140
|
+
"model ignores roster_id AND location_id args. For a " \
|
|
141
|
+
"location-scoped attendance report use CheckInReport " \
|
|
142
|
+
"--location <id> instead.",
|
|
132
143
|
example: "wiq reports run CheckInSummaryReport --start 2026-05-01 --end 2026-05-31"
|
|
133
144
|
},
|
|
134
145
|
"CheckInFeedReport" => {
|
|
@@ -138,11 +149,12 @@ module Wiq
|
|
|
138
149
|
recommended: true,
|
|
139
150
|
notes: "Useful for \"who came to the club today and what registrations " \
|
|
140
151
|
"did they have at check-in time.\" Larger payload than the " \
|
|
141
|
-
"summary."
|
|
152
|
+
"summary. Always team-wide: the model ignores roster_id AND " \
|
|
153
|
+
"location_id args.",
|
|
142
154
|
example: "wiq reports run CheckInFeedReport --start 2026-05-01 --end 2026-05-31"
|
|
143
155
|
},
|
|
144
156
|
"PracticeAttendanceReport" => {
|
|
145
|
-
args: %w[roster_id],
|
|
157
|
+
args: %w[roster_id location_id],
|
|
146
158
|
dates: :required,
|
|
147
159
|
desc: "Practice-event attendance roll-up across a date range",
|
|
148
160
|
recommended: false,
|
|
@@ -153,7 +165,7 @@ module Wiq
|
|
|
153
165
|
"use CheckInSummaryReport or CheckInFeedReport instead."
|
|
154
166
|
},
|
|
155
167
|
"LastPracticeAttendedReport" => {
|
|
156
|
-
args: %w[roster_id],
|
|
168
|
+
args: %w[roster_id location_id],
|
|
157
169
|
dates: :optional,
|
|
158
170
|
desc: "Days since last practice attended, per wrestler",
|
|
159
171
|
recommended: true,
|
|
@@ -161,7 +173,7 @@ module Wiq
|
|
|
161
173
|
"practice in a while — particularly for seasonal clubs."
|
|
162
174
|
},
|
|
163
175
|
"ChurnRiskReport" => {
|
|
164
|
-
args: %w[roster_id days_threshold],
|
|
176
|
+
args: %w[roster_id location_id days_threshold],
|
|
165
177
|
dates: :optional,
|
|
166
178
|
desc: "Active recurring subscribers who haven't checked in within a window",
|
|
167
179
|
recommended: true,
|
|
@@ -172,7 +184,7 @@ module Wiq
|
|
|
172
184
|
example: "wiq reports run ChurnRiskReport --roster 0 --days-threshold 30"
|
|
173
185
|
},
|
|
174
186
|
"CheckInReport" => {
|
|
175
|
-
args: %w[roster_id],
|
|
187
|
+
args: %w[roster_id location_id],
|
|
176
188
|
dates: :required,
|
|
177
189
|
desc: "Extended attendance — one row per check-in INCLUDING Q&A responses",
|
|
178
190
|
notes: "UI labels this \"Attendance Extended (with questions).\" Same " \
|
|
@@ -327,6 +339,14 @@ module Wiq
|
|
|
327
339
|
Common args (only those documented in TYPES are honored
|
|
328
340
|
server-side):
|
|
329
341
|
--roster <id> roster_id (0 = all rosters)
|
|
342
|
+
--location <id> location_id — scope the wrestler set to
|
|
343
|
+
one location (wrestlers on ANY roster at
|
|
344
|
+
that location, deduped to one row each).
|
|
345
|
+
Precedence: a specific --roster <id> (> 0)
|
|
346
|
+
WINS over --location; pass --location
|
|
347
|
+
alone (or with --roster 0) to get
|
|
348
|
+
location scoping. Discover ids via
|
|
349
|
+
`wiq locations list`.
|
|
330
350
|
--paid-session <id> paid_session_id (0 = all, UsawExport only)
|
|
331
351
|
--event <id> event_id (EventStatsReport)
|
|
332
352
|
--fundraiser <id> fundraiser_id (Fundraiser* reports)
|
|
@@ -341,10 +361,31 @@ module Wiq
|
|
|
341
361
|
cap, default 5-minute timeout. Pass --no-wait to return the
|
|
342
362
|
report row immediately after submission (status=queued or
|
|
343
363
|
processing) and poll later with `wiq reports show <id> --wait`.
|
|
364
|
+
|
|
365
|
+
Result shape (vrow default / --v1):
|
|
366
|
+
The CLI requests the row/CSV shape (version "vrow") by default —
|
|
367
|
+
`result.rows.objects` with the first row being the headers, the
|
|
368
|
+
exact layout behind the "Download" buttons in the WIQ web UI.
|
|
369
|
+
Most reports emit only this shape and ignore the version.
|
|
370
|
+
|
|
371
|
+
For RosterReport, vrow is the ONLY shape carrying the "Added to
|
|
372
|
+
roster at" column (roster_memberships.created_at — when a
|
|
373
|
+
wrestler landed on that roster, distinct from their registration
|
|
374
|
+
date). That column is populated only for a specific roster: pass
|
|
375
|
+
--roster <id> with id > 0, NOT --roster 0 ("all wrestlers"),
|
|
376
|
+
since a wrestler can sit on multiple rosters.
|
|
377
|
+
|
|
378
|
+
Pass --v1 for the legacy structured-JSON shape. Only
|
|
379
|
+
RosterReport, UsawReport, and PaidSessionAccountingReport differ
|
|
380
|
+
under it (fuller per-wrestler objects); for those reports v1
|
|
381
|
+
drops the "Added to roster at" column.
|
|
344
382
|
DESC
|
|
345
383
|
method_option :start, type: :string, desc: "YYYY-MM-DD"
|
|
346
384
|
method_option :end, type: :string, desc: "YYYY-MM-DD"
|
|
347
385
|
method_option :roster, type: :numeric, desc: "args.roster_id (0 = all rosters)"
|
|
386
|
+
method_option :location, type: :numeric,
|
|
387
|
+
desc: "args.location_id — scope wrestlers to one location " \
|
|
388
|
+
"(a specific --roster <id> > 0 takes precedence)"
|
|
348
389
|
method_option :paid_session, type: :numeric, desc: "args.paid_session_id"
|
|
349
390
|
method_option :event, type: :numeric, desc: "args.event_id"
|
|
350
391
|
method_option :fundraiser, type: :numeric, desc: "args.fundraiser_id"
|
|
@@ -358,6 +399,11 @@ module Wiq
|
|
|
358
399
|
desc: "args.days_threshold (ChurnRiskReport)"
|
|
359
400
|
method_option :name, type: :string, desc: "Display name (default: CLI <type> <range>)"
|
|
360
401
|
method_option :season, type: :numeric, desc: "Resolve to paid_session_id via overlap with calendar year"
|
|
402
|
+
method_option :v1, type: :boolean, default: false,
|
|
403
|
+
desc: "Request the legacy v1 structured-JSON shape instead of the default " \
|
|
404
|
+
"row/CSV (vrow). Only RosterReport/UsawReport/PaidSessionAccountingReport " \
|
|
405
|
+
"differ; v1 returns fuller per-wrestler objects but drops RosterReport's " \
|
|
406
|
+
"\"Added to roster at\" column."
|
|
361
407
|
method_option :wait, type: :boolean, default: true
|
|
362
408
|
method_option :timeout, type: :numeric, default: 300
|
|
363
409
|
map "run" => :run_report
|
|
@@ -367,7 +413,7 @@ module Wiq
|
|
|
367
413
|
body = {
|
|
368
414
|
report: {
|
|
369
415
|
type: type,
|
|
370
|
-
version:
|
|
416
|
+
version: report_version,
|
|
371
417
|
name: options[:name] || default_name(type),
|
|
372
418
|
start_at: options[:start],
|
|
373
419
|
end_at: options[:end],
|
|
@@ -469,6 +515,18 @@ module Wiq
|
|
|
469
515
|
end
|
|
470
516
|
|
|
471
517
|
no_commands do
|
|
518
|
+
# The API recognizes two report versions: "vrow" (the row/CSV shape
|
|
519
|
+
# behind the web Download buttons) and "v1" (legacy structured JSON).
|
|
520
|
+
# Only RosterReport/UsawReport/PaidSessionAccountingReport branch on
|
|
521
|
+
# it; every other report emits rows regardless. vrow is the de facto
|
|
522
|
+
# standard and is the only shape carrying RosterReport's "Added to
|
|
523
|
+
# roster at" column, so the CLI defaults to it for a uniform surface.
|
|
524
|
+
# --v1 is an escape hatch to the fuller structured objects on those
|
|
525
|
+
# three reports.
|
|
526
|
+
def report_version
|
|
527
|
+
options[:v1] ? "v1" : "vrow"
|
|
528
|
+
end
|
|
529
|
+
|
|
472
530
|
def build_args(type)
|
|
473
531
|
if options[:season]
|
|
474
532
|
resolver = Wiq::SeasonResolver.new(client)
|
|
@@ -488,6 +546,7 @@ module Wiq
|
|
|
488
546
|
|
|
489
547
|
args = {}
|
|
490
548
|
args["roster_id"] = options[:roster] if options[:roster] || options[:roster] == 0
|
|
549
|
+
args["location_id"] = options[:location] if options[:location]
|
|
491
550
|
args["paid_session_id"] = options[:paid_session] if options[:paid_session] || options[:paid_session] == 0
|
|
492
551
|
args["event_id"] = options[:event] if options[:event]
|
|
493
552
|
args["fundraiser_id"] = options[:fundraiser] if options[:fundraiser]
|
data/lib/wiq/commands/rosters.rb
CHANGED
|
@@ -17,12 +17,19 @@ module Wiq
|
|
|
17
17
|
exact name. Some teams tag rosters with
|
|
18
18
|
conventions like "2025-26".
|
|
19
19
|
|
|
20
|
+
--location <id> filters server-side (Ransack q[location_id_eq]) to
|
|
21
|
+
rosters stamped with that structured location. Discover ids via
|
|
22
|
+
`wiq locations list`. Rosters with no location are excluded when
|
|
23
|
+
the filter is on. Each roster row embeds its location object (or
|
|
24
|
+
null) so you can also group client-side without the filter.
|
|
25
|
+
|
|
20
26
|
Each roster row embeds roster_syncers and taggings, which is what
|
|
21
27
|
--season uses to filter without needing extra calls.
|
|
22
28
|
DESC
|
|
23
29
|
method_option :season, type: :numeric,
|
|
24
30
|
desc: "Filter to rosters whose syncers point at paid sessions overlapping this year"
|
|
25
31
|
method_option :season_tag, type: :string, desc: "Filter to rosters carrying this tag"
|
|
32
|
+
method_option :location, type: :numeric, desc: "Filter to rosters at one location id"
|
|
26
33
|
method_option :archived, type: :boolean, desc: "Show only archived (true) or active (false)"
|
|
27
34
|
method_option :all, type: :boolean, default: false
|
|
28
35
|
def list
|
|
@@ -30,6 +37,7 @@ module Wiq
|
|
|
30
37
|
unless options[:archived].nil?
|
|
31
38
|
params["q[archived_eq]"] = options[:archived]
|
|
32
39
|
end
|
|
40
|
+
params["q[location_id_eq]"] = options[:location] if options[:location]
|
|
33
41
|
|
|
34
42
|
records, total = fetch_index("/api/v1/rosters", params, key: "rosters")
|
|
35
43
|
|
|
@@ -20,6 +20,10 @@ module Wiq
|
|
|
20
20
|
--first-name q[first_name_cont]
|
|
21
21
|
--last-name q[last_name_cont]
|
|
22
22
|
--roster <id> q[rosters_id_eq] — filter to one roster
|
|
23
|
+
--location <id> location_id (dedicated param, not Ransack) —
|
|
24
|
+
wrestlers on ANY roster at that location.
|
|
25
|
+
Composes with the other filters. Discover
|
|
26
|
+
ids via `wiq locations list`.
|
|
23
27
|
--weight-class q[weight_class_numeric_eq] — exact numeric
|
|
24
28
|
--academic-class q[academic_class_eq] (senior, junior, …)
|
|
25
29
|
--age q[age_eq]
|
|
@@ -43,6 +47,8 @@ module Wiq
|
|
|
43
47
|
method_option :first_name, type: :string, desc: "First name (contains)"
|
|
44
48
|
method_option :last_name, type: :string, desc: "Last name (contains)"
|
|
45
49
|
method_option :roster, type: :numeric, desc: "Filter to a single roster id"
|
|
50
|
+
method_option :location, type: :numeric,
|
|
51
|
+
desc: "Filter to wrestlers on any roster at this location id"
|
|
46
52
|
method_option :weight_class, type: :string,
|
|
47
53
|
desc: "Weight class (exact numeric, e.g. 132)"
|
|
48
54
|
method_option :academic_class, type: :string,
|
|
@@ -107,6 +113,7 @@ module Wiq
|
|
|
107
113
|
params["q[first_name_cont]"] = options[:first_name] if options[:first_name]
|
|
108
114
|
params["q[last_name_cont]"] = options[:last_name] if options[:last_name]
|
|
109
115
|
params["q[rosters_id_eq]"] = options[:roster] if options[:roster]
|
|
116
|
+
params["location_id"] = options[:location] if options[:location]
|
|
110
117
|
params["q[weight_class_numeric_eq]"] = options[:weight_class] if options[:weight_class]
|
|
111
118
|
params["q[academic_class_eq]"] = options[:academic_class] if options[:academic_class]
|
|
112
119
|
params["q[age_eq]"] = options[:age] if options[:age]
|
|
@@ -130,6 +137,7 @@ module Wiq
|
|
|
130
137
|
bits = []
|
|
131
138
|
bits << "matching #{options[:query].inspect}" if options[:query]
|
|
132
139
|
bits << "in roster #{options[:roster]}" if options[:roster]
|
|
140
|
+
bits << "at location #{options[:location]}" if options[:location]
|
|
133
141
|
bits << "weight class #{options[:weight_class]}" if options[:weight_class]
|
|
134
142
|
bits << "profile_type=#{options[:profile_type]}" if profile_type_filter? && options[:profile_type] != "teammate"
|
|
135
143
|
bits.empty? ? "" : " (#{bits.join(", ")})"
|
data/lib/wiq/version.rb
CHANGED
data/lib/wiq.rb
CHANGED
|
@@ -20,6 +20,7 @@ require "wiq/commands/registrations"
|
|
|
20
20
|
require "wiq/commands/metrics"
|
|
21
21
|
require "wiq/commands/events"
|
|
22
22
|
require "wiq/commands/rosters"
|
|
23
|
+
require "wiq/commands/locations"
|
|
23
24
|
require "wiq/commands/prospects"
|
|
24
25
|
require "wiq/commands/prospect_families"
|
|
25
26
|
require "wiq/commands/workflows"
|
data/share/skills/wiq/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: wiq
|
|
3
|
-
description: Use this skill when the user asks about their WrestlingIQ data — rosters, attendance, check-ins, paid sessions and registrations, the prospects/leads pipeline, financial metrics, reports, USAW/AAU memberships, fundraising,
|
|
3
|
+
description: Use this skill when the user asks about their WrestlingIQ data — rosters, attendance, check-ins, paid sessions and registrations, the prospects/leads pipeline, financial metrics, reports, USAW/AAU memberships, fundraising, online store orders, or per-location/site breakdowns for multi-gym clubs. The `wiq` CLI provides read-only access to /api/v1 via personal access tokens. Recognize phrasings like "how is our pipeline?", "who came to practice this week?", "show me the roster", "what's our MRR?", "which kids need USAW renewal?", "how is the Eastside gym doing?", or anything that maps to a wrestling club's admin workflows.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# WrestlingIQ CLI Skill
|
|
@@ -172,6 +172,11 @@ Key reports an agent should know by heart:
|
|
|
172
172
|
within N days (7, 14, 30, 60, 90). Requires `--days-threshold`.
|
|
173
173
|
- **`RosterReport`** — Roster snapshot with optional custom columns via
|
|
174
174
|
`--append-properties <q_ids>`. Discover ids via `wiq registrations questions`.
|
|
175
|
+
The default (row/CSV) shape carries the **"Added to roster at"** column
|
|
176
|
+
(`roster_memberships.created_at` — when a wrestler landed on that roster,
|
|
177
|
+
NOT their registration date). Requires a specific `--roster <id>` (id > 0);
|
|
178
|
+
it's blank for `--roster 0`. `--v1` returns fuller per-wrestler objects but
|
|
179
|
+
drops that column.
|
|
175
180
|
- **`LastPracticeAttendedReport`** — "Who hasn't been to practice in a
|
|
176
181
|
while?"
|
|
177
182
|
- **`PaidSessionAccountingReport`** (admin_only) — Line-item charges for
|
|
@@ -194,6 +199,18 @@ wiq reports run <Type> --start <date> --end <date> [args]
|
|
|
194
199
|
processing → ready` (terminal) | `failed` (terminal). `result` is the
|
|
195
200
|
type-specific jsonb payload.
|
|
196
201
|
|
|
202
|
+
**Result shape — vrow default (`--v1` escape hatch).** The CLI requests
|
|
203
|
+
the row/CSV shape (`version: "vrow"`) by default: `result.rows.objects`
|
|
204
|
+
with the first row being the header — identical to the web "Download"
|
|
205
|
+
buttons, and a uniform shape across every report type. Most reports emit
|
|
206
|
+
only this shape and ignore the version. Only `RosterReport`, `UsawReport`,
|
|
207
|
+
and `PaidSessionAccountingReport` also support a legacy v1 shape
|
|
208
|
+
(structured JSON objects) via `--v1`, which returns fuller per-wrestler
|
|
209
|
+
data but drops RosterReport's **"Added to roster at"** column. If a user
|
|
210
|
+
asks when a wrestler joined a roster (e.g. roster-join → first-practice
|
|
211
|
+
latency), `wiq reports run RosterReport --roster <id>` is the answer — the
|
|
212
|
+
join date is in the default output.
|
|
213
|
+
|
|
197
214
|
## Common gotchas
|
|
198
215
|
|
|
199
216
|
- **`roster_id=0` = "all rosters"** in report args. UI convention; if
|
|
@@ -206,9 +223,14 @@ type-specific jsonb payload.
|
|
|
206
223
|
resolves to paid_session ids whose date range overlaps the calendar
|
|
207
224
|
year, then filters client-side. There's no first-class Season entity
|
|
208
225
|
in WIQ.
|
|
209
|
-
-
|
|
210
|
-
|
|
211
|
-
|
|
226
|
+
- **Legacy free-text `Event.location` vs structured locations.** Old
|
|
227
|
+
events carry a free-text `location` string; the serialized `location`
|
|
228
|
+
field is the display form (structured Location name/address when
|
|
229
|
+
`location_id` is set, else the legacy text). `--location` filters only
|
|
230
|
+
match the structured `location_id` — events, rosters, and paid sessions
|
|
231
|
+
with NO location set are excluded from filtered listings, so an empty
|
|
232
|
+
filtered result doesn't mean "nothing happened", it may mean "nothing
|
|
233
|
+
is stamped with that location yet."
|
|
212
234
|
- **Index responses are wrapped.** Every `/api/v1` index returns
|
|
213
235
|
`{"<resource>": [...]}` — the CLI unwraps internally, but if you ever
|
|
214
236
|
hit the API directly remember to unwrap.
|
|
@@ -321,13 +343,58 @@ For exhaustive exports go through `wiq reports run RosterReport`
|
|
|
321
343
|
`profile_type=teammate` (matching the WIQ web UI default); pass
|
|
322
344
|
`--profile-type alumnus|guest|all` to widen.
|
|
323
345
|
|
|
346
|
+
## Locations (multi-site clubs)
|
|
347
|
+
|
|
348
|
+
WIQ has a structured Location model (name + street address, per team).
|
|
349
|
+
Multi-gym clubs stamp rosters, events, and paid sessions with a
|
|
350
|
+
location; single-site clubs usually have none, and every `--location`
|
|
351
|
+
flag is simply irrelevant for them.
|
|
352
|
+
|
|
353
|
+
Discover ids first — this is the anchor for everything below:
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
wiq locations list # id, name, address, archived
|
|
357
|
+
wiq locations list --include-archived
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Then scope any of these surfaces:
|
|
361
|
+
|
|
362
|
+
| Command | Flag | Semantics |
|
|
363
|
+
| --- | --- | --- |
|
|
364
|
+
| `wiq rosters list` | `--location <id>` | Rosters stamped with that location (`q[location_id_eq]`) |
|
|
365
|
+
| `wiq events list` | `--location <id> [<id>...]` | Events at those locations (repeatable; unset-location events excluded) |
|
|
366
|
+
| `wiq paid_sessions list` | `--location <id>` | Sessions stamped with that location |
|
|
367
|
+
| `wiq wrestlers list` | `--location <id>` | Wrestlers on ANY roster at that location; composes with other filters |
|
|
368
|
+
| `wiq metrics show <name>` | `--location <id>` | Per-location finance metrics (the payment-dashboard filter) |
|
|
369
|
+
| `wiq reports run <Type>` | `--location <id>` | Scopes the wrestler set for the 13 location-aware report types |
|
|
370
|
+
|
|
371
|
+
Three gotchas an agent must know:
|
|
372
|
+
|
|
373
|
+
1. **Reports precedence:** a specific `--roster <id>` (> 0) WINS over
|
|
374
|
+
`--location` in report args. Pass `--location` alone (or with
|
|
375
|
+
`--roster 0`) to get location scoping. A wrestler on multiple rosters
|
|
376
|
+
at the location collapses to one row; RosterReport's "Added to roster
|
|
377
|
+
at" becomes their EARLIEST membership across that location's rosters.
|
|
378
|
+
`CheckInSummaryReport` / `CheckInFeedReport` ignore both args
|
|
379
|
+
entirely (always team-wide) — use `CheckInReport --location <id>` for
|
|
380
|
+
location-scoped attendance.
|
|
381
|
+
2. **Metrics fail silent, not loud:** an unknown or foreign `--location`
|
|
382
|
+
id on `wiq metrics show` silently falls back to ALL locations —
|
|
383
|
+
team-wide numbers, no error. Verify the id against
|
|
384
|
+
`wiq locations list` before quoting per-site revenue to the user.
|
|
385
|
+
3. **Nothing is auto-stamped retroactively.** Filters only match records
|
|
386
|
+
whose `location_id` is set. Empty filtered results on a club that
|
|
387
|
+
just adopted locations usually mean unstamped data, not zero
|
|
388
|
+
activity. Rosters/events/paid_sessions embed their `location` object
|
|
389
|
+
(or null) in list payloads, so you can check coverage cheaply.
|
|
390
|
+
|
|
324
391
|
## What's NOT available (yet)
|
|
325
392
|
|
|
326
393
|
The CLI is read-only by design except for report submission. You
|
|
327
394
|
cannot via this CLI:
|
|
328
395
|
|
|
329
396
|
- Create/edit prospects, families, notes, check-ins, events, paid
|
|
330
|
-
sessions, rosters, or any other resource
|
|
397
|
+
sessions, rosters, locations, or any other resource
|
|
331
398
|
- Mint, list, or revoke PATs (use the web UI at
|
|
332
399
|
`<host>/settings/personal_access_tokens`)
|
|
333
400
|
- Mark attendance, advance prospect stages, log contact notes
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wiq-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- WrestlingIQ
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: thor
|
|
@@ -90,6 +90,7 @@ files:
|
|
|
90
90
|
- lib/wiq/commands/check_ins.rb
|
|
91
91
|
- lib/wiq/commands/doctor.rb
|
|
92
92
|
- lib/wiq/commands/events.rb
|
|
93
|
+
- lib/wiq/commands/locations.rb
|
|
93
94
|
- lib/wiq/commands/metrics.rb
|
|
94
95
|
- lib/wiq/commands/paid_sessions.rb
|
|
95
96
|
- lib/wiq/commands/prospect_families.rb
|