@wonsukchoi/crondex 0.20.0 → 0.21.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.
- package/README.md +5 -1
- package/catalog.json +720 -17
- package/jobs/fieldservice/maintenance-contract-renewal-check.yaml +36 -0
- package/jobs/fieldservice/parts-low-stock-reorder-check.yaml +29 -0
- package/jobs/fieldservice/tech-eta-no-show-check.yaml +32 -0
- package/jobs/fieldservice/tech-license-renewal-check.yaml +36 -0
- package/jobs/fieldservice/unpaid-invoice-aging-check.yaml +35 -0
- package/jobs/fieldservice/unresolved-callback-tracker.yaml +35 -0
- package/jobs/fieldservice/warranty-claim-expiry-check.yaml +35 -0
- package/jobs/hr/{payroll-run-reminder.yaml → payroll-cutoff-checklist-reminder.yaml} +1 -1
- package/jobs/publishing/arc-review-copy-followup.yaml +35 -0
- package/jobs/publishing/isbn-registration-tracker.yaml +35 -0
- package/jobs/publishing/manuscript-deadline-tracker.yaml +34 -0
- package/jobs/publishing/permissions-clearance-tracker.yaml +36 -0
- package/jobs/publishing/print-run-reorder-threshold-check.yaml +32 -0
- package/jobs/publishing/rights-license-expiry-check.yaml +35 -0
- package/jobs/publishing/royalty-statement-due-check.yaml +33 -0
- package/jobs/spa/appointment-no-show-tracker.yaml +46 -0
- package/jobs/spa/gift-card-expiry-check.yaml +35 -0
- package/jobs/spa/license-renewal-tracker.yaml +35 -0
- package/jobs/spa/membership-unused-session-expiry-check.yaml +35 -0
- package/jobs/spa/product-chemical-expiry-check.yaml +35 -0
- package/jobs/spa/retail-product-low-stock-check.yaml +26 -0
- package/jobs/spa/safety-inspection-due-reminder.yaml +33 -0
- package/jobs/telecom/circuit-outage-detection.yaml +38 -0
- package/jobs/telecom/circuit-provisioning-order-aging.yaml +36 -0
- package/jobs/telecom/cpe-firmware-update-tracker.yaml +45 -0
- package/jobs/telecom/link-capacity-threshold-alert.yaml +37 -0
- package/jobs/telecom/peering-transit-contract-renewal-check.yaml +36 -0
- package/jobs/telecom/service-ticket-churn-risk-review.yaml +56 -0
- package/jobs/telecom/sla-uptime-breach-tracker.yaml +36 -0
- package/lib/category-descriptions.js +4 -0
- package/lib/duplicates-allowlist.js +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
id: product-chemical-expiry-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Product & Chemical Expiry Check
|
|
4
|
+
description: >
|
|
5
|
+
Flags skincare products, dye lots, wax, and other chemical inventory
|
|
6
|
+
approaching their expiration or period-after-opening date. Use this if
|
|
7
|
+
an esthetician or colorist has ever applied a product past its safe-use
|
|
8
|
+
date because the expiry label was never checked against today's date.
|
|
9
|
+
category: spa
|
|
10
|
+
tags: [spa, inventory, expiry, safety, chemicals]
|
|
11
|
+
schedule: "0 6 * * 1"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
awk -F',' -v days="{{warn_days_before}}" '
|
|
16
|
+
NR==1 {next}
|
|
17
|
+
{
|
|
18
|
+
cmd = "date -d \"" $2 "\" +%s 2>/dev/null || date -j -f %Y-%m-%d \"" $2 "\" +%s 2>/dev/null";
|
|
19
|
+
cmd | getline exp_epoch; close(cmd);
|
|
20
|
+
"date +%s" | getline now_epoch; close("date +%s");
|
|
21
|
+
diff_days = (exp_epoch - now_epoch) / 86400;
|
|
22
|
+
if (diff_days <= days) {
|
|
23
|
+
printf "EXPIRING/EXPIRED: %s (lot %s) — expires %s (%d days)\n", $1, $3, $2, diff_days;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
' "{{product_expiry_csv_path}}"
|
|
27
|
+
variables:
|
|
28
|
+
product_expiry_csv_path:
|
|
29
|
+
default: "./product-expiry.csv"
|
|
30
|
+
description: "Path to a CSV with columns: product_name,expiry_or_pao_date (YYYY-MM-DD),lot_number."
|
|
31
|
+
warn_days_before:
|
|
32
|
+
default: 14
|
|
33
|
+
description: How many days before expiry to start warning, so stock can be used up or pulled before it goes bad.
|
|
34
|
+
compatible_agents: [generic, claude, codex]
|
|
35
|
+
notes: Applying an expired chemical (peel, dye, wax) can cause skin reactions — pull flagged items from active use immediately, don't just discount and sell through.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
id: retail-product-low-stock-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Retail Product Low-Stock Check
|
|
4
|
+
description: >
|
|
5
|
+
Scans your retail/backbar inventory log and flags skincare, haircare, or
|
|
6
|
+
nail products at or below reorder point. Use this if a stylist or
|
|
7
|
+
esthetician has ever reached for a product mid-service and found the
|
|
8
|
+
shelf empty because nobody was watching the count.
|
|
9
|
+
category: spa
|
|
10
|
+
tags: [spa, retail, inventory, restock]
|
|
11
|
+
schedule: "0 7 * * 1"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
awk -F',' '
|
|
16
|
+
NR==1 {next}
|
|
17
|
+
$2 <= $3 {
|
|
18
|
+
printf "LOW STOCK: %s — %d on hand, reorder point %d\n", $1, $2, $3;
|
|
19
|
+
}
|
|
20
|
+
' "{{inventory_csv_path}}"
|
|
21
|
+
variables:
|
|
22
|
+
inventory_csv_path:
|
|
23
|
+
default: "./retail-inventory.csv"
|
|
24
|
+
description: "Path to a CSV with columns: product_name,quantity_on_hand,reorder_point."
|
|
25
|
+
compatible_agents: [generic, claude, codex]
|
|
26
|
+
notes: Pair the reorder point with your supplier's typical lead time so you never hit zero mid-service.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
id: safety-inspection-due-reminder
|
|
2
|
+
version: 1
|
|
3
|
+
name: Health & Safety Inspection Due Reminder
|
|
4
|
+
description: >
|
|
5
|
+
Warns before a health department, board-of-cosmetology, or fire/safety
|
|
6
|
+
inspection is expected, based on your jurisdiction's typical interval.
|
|
7
|
+
Use this if an inspector has ever shown up to a treatment room that
|
|
8
|
+
wasn't ready because nobody was tracking when the last inspection
|
|
9
|
+
happened.
|
|
10
|
+
category: spa
|
|
11
|
+
tags: [spa, compliance, inspection, safety]
|
|
12
|
+
schedule: "0 8 1 * *"
|
|
13
|
+
timezone: "UTC"
|
|
14
|
+
runner: shell
|
|
15
|
+
command: >
|
|
16
|
+
today=$(date +%s);
|
|
17
|
+
last_ts=$(date -d "{{last_inspection_date}}" +%s 2>/dev/null || date -jf "%Y-%m-%d" "{{last_inspection_date}}" +%s);
|
|
18
|
+
days_since=$(( (today - last_ts) / 86400 ));
|
|
19
|
+
days_left=$(( {{typical_interval_days}} - days_since ));
|
|
20
|
+
if [ "$days_left" -le "{{warn_days}}" ]; then echo "WARNING: next inspection likely due within $days_left days (last was {{last_inspection_date}})"; exit 1;
|
|
21
|
+
else echo "OK: next inspection likely due in about $days_left days"; fi
|
|
22
|
+
variables:
|
|
23
|
+
last_inspection_date:
|
|
24
|
+
default: "2026-01-01"
|
|
25
|
+
description: Date of the last health/safety/board inspection (YYYY-MM-DD).
|
|
26
|
+
typical_interval_days:
|
|
27
|
+
default: 365
|
|
28
|
+
description: Typical number of days between inspections in your jurisdiction.
|
|
29
|
+
warn_days:
|
|
30
|
+
default: 21
|
|
31
|
+
description: Days before the estimated next inspection to start warning.
|
|
32
|
+
compatible_agents: [generic, claude, codex]
|
|
33
|
+
notes: This is an estimate based on your jurisdiction's typical cadence, not a confirmed scheduled date — most boards don't publish inspection dates in advance.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
id: circuit-outage-detection
|
|
2
|
+
version: 1
|
|
3
|
+
name: Circuit Outage Detection
|
|
4
|
+
description: >
|
|
5
|
+
Pings each monitored circuit endpoint and flags any that are down.
|
|
6
|
+
Use this if a customer circuit has ever gone dark and nobody on your
|
|
7
|
+
team noticed until the customer called in.
|
|
8
|
+
category: telecom
|
|
9
|
+
tags: [telecom, outage, monitoring, circuits]
|
|
10
|
+
schedule: "*/5 * * * *"
|
|
11
|
+
timezone: "UTC"
|
|
12
|
+
runner: shell
|
|
13
|
+
command: >
|
|
14
|
+
down=0;
|
|
15
|
+
while IFS=',' read -r circuit_id endpoint _rest; do
|
|
16
|
+
[ "$circuit_id" = "circuit_id" ] && continue;
|
|
17
|
+
[ -z "$endpoint" ] && continue;
|
|
18
|
+
if ! ping -c "{{ping_count}}" -W "{{ping_timeout_sec}}" "$endpoint" >/dev/null 2>&1; then
|
|
19
|
+
echo "DOWN: circuit $circuit_id ($endpoint) is not responding";
|
|
20
|
+
down=1;
|
|
21
|
+
fi;
|
|
22
|
+
done < "{{circuits_csv_path}}";
|
|
23
|
+
if [ "$down" -eq 0 ]; then echo "OK: all monitored circuits responding"; else exit 1; fi
|
|
24
|
+
variables:
|
|
25
|
+
circuits_csv_path:
|
|
26
|
+
default: "./circuits.csv"
|
|
27
|
+
description: "Path to a CSV with columns: circuit_id,endpoint (IP or hostname to ping)."
|
|
28
|
+
ping_count:
|
|
29
|
+
default: 2
|
|
30
|
+
description: Number of ping probes per circuit before declaring it down.
|
|
31
|
+
ping_timeout_sec:
|
|
32
|
+
default: 3
|
|
33
|
+
description: Timeout in seconds per ping probe.
|
|
34
|
+
compatible_agents: [generic, claude, codex]
|
|
35
|
+
notes: >
|
|
36
|
+
Uses ICMP ping as a cheap reachability check — swap in an SNMP or NMS API
|
|
37
|
+
poll if your circuits are behind firewalls that block ICMP. Read-only,
|
|
38
|
+
no state changes.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
id: circuit-provisioning-order-aging
|
|
2
|
+
version: 1
|
|
3
|
+
name: Circuit Provisioning Order Aging Check
|
|
4
|
+
description: >
|
|
5
|
+
Flags circuit orders that were placed but never activated within a
|
|
6
|
+
target number of days. Use this if a provisioning order has ever sat
|
|
7
|
+
in limbo for weeks because the install date fell through the cracks
|
|
8
|
+
between sales, the carrier, and the field tech.
|
|
9
|
+
category: telecom
|
|
10
|
+
tags: [telecom, provisioning, circuits, orders]
|
|
11
|
+
schedule: "0 8 * * 1-5"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
awk -F',' -v max_days="{{max_days_to_activate}}" '
|
|
16
|
+
NR==1 {next}
|
|
17
|
+
$3 != "" {next}
|
|
18
|
+
{
|
|
19
|
+
cmd = "date -d \"" $2 "\" +%s 2>/dev/null || date -j -f %Y-%m-%d \"" $2 "\" +%s 2>/dev/null";
|
|
20
|
+
cmd | getline order_epoch; close(cmd);
|
|
21
|
+
"date +%s" | getline now_epoch; close("date +%s");
|
|
22
|
+
age_days = (now_epoch - order_epoch) / 86400;
|
|
23
|
+
if (age_days >= max_days) {
|
|
24
|
+
printf "AGING ORDER: %s ordered %s (%d days ago), still not activated\n", $1, $2, age_days;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
' "{{orders_csv_path}}"
|
|
28
|
+
variables:
|
|
29
|
+
orders_csv_path:
|
|
30
|
+
default: "./provisioning-orders.csv"
|
|
31
|
+
description: "Path to a CSV with columns: order_id,order_date (YYYY-MM-DD),activated_date (blank if not yet activated)."
|
|
32
|
+
max_days_to_activate:
|
|
33
|
+
default: 21
|
|
34
|
+
description: Days after order date to flag as aging if still not activated.
|
|
35
|
+
compatible_agents: [generic, claude, codex]
|
|
36
|
+
notes: Assumes order/activation dates are updated in the CSV from your provisioning ticketing system.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
id: cpe-firmware-update-tracker
|
|
2
|
+
version: 1
|
|
3
|
+
name: CPE Firmware/Warranty Update Tracker
|
|
4
|
+
description: >
|
|
5
|
+
Checks deployed customer-premises equipment against current firmware
|
|
6
|
+
versions and warranty expiry dates, flagging anything out of date or
|
|
7
|
+
soon out of warranty. Use this if a modem or router has ever been
|
|
8
|
+
running years-old firmware with a known vulnerability because nobody
|
|
9
|
+
was tracking the fleet's patch level.
|
|
10
|
+
category: telecom
|
|
11
|
+
tags: [telecom, cpe, firmware, warranty]
|
|
12
|
+
schedule: "0 8 * * 1"
|
|
13
|
+
timezone: "UTC"
|
|
14
|
+
runner: shell
|
|
15
|
+
command: >
|
|
16
|
+
awk -F',' -v target_fw="{{target_firmware_version}}" -v warn_days="{{warranty_warn_days}}" '
|
|
17
|
+
NR==1 {next}
|
|
18
|
+
{
|
|
19
|
+
device=$1; fw=$2; warranty_end=$3;
|
|
20
|
+
if (fw != target_fw) {
|
|
21
|
+
printf "OUTDATED FIRMWARE: %s running %s, target is %s\n", device, fw, target_fw;
|
|
22
|
+
}
|
|
23
|
+
if (warranty_end != "") {
|
|
24
|
+
cmd = "date -d \"" warranty_end "\" +%s 2>/dev/null || date -j -f %Y-%m-%d \"" warranty_end "\" +%s 2>/dev/null";
|
|
25
|
+
cmd | getline end_epoch; close(cmd);
|
|
26
|
+
"date +%s" | getline now_epoch; close("date +%s");
|
|
27
|
+
diff_days = (end_epoch - now_epoch) / 86400;
|
|
28
|
+
if (diff_days <= warn_days) {
|
|
29
|
+
printf "WARRANTY EXPIRING: %s warranty ends %s (%d days)\n", device, warranty_end, diff_days;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
' "{{cpe_inventory_csv_path}}"
|
|
34
|
+
variables:
|
|
35
|
+
cpe_inventory_csv_path:
|
|
36
|
+
default: "./cpe-inventory.csv"
|
|
37
|
+
description: "Path to a CSV with columns: device_id,firmware_version,warranty_end_date (YYYY-MM-DD, blank if unknown)."
|
|
38
|
+
target_firmware_version:
|
|
39
|
+
default: "1.0.0"
|
|
40
|
+
description: The firmware version the fleet should be running.
|
|
41
|
+
warranty_warn_days:
|
|
42
|
+
default: 30
|
|
43
|
+
description: Days before warranty expiry to start warning.
|
|
44
|
+
compatible_agents: [generic, claude, codex]
|
|
45
|
+
notes: Assumes CPE inventory is exported from your provisioning/asset system into the CSV before this runs.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
id: link-capacity-threshold-alert
|
|
2
|
+
version: 1
|
|
3
|
+
name: Link Capacity Threshold Alert
|
|
4
|
+
description: >
|
|
5
|
+
Checks a link's current bandwidth utilization against a warning
|
|
6
|
+
threshold so you can upgrade capacity before customers notice
|
|
7
|
+
congestion. Use this if a trunk or uplink has ever saturated during
|
|
8
|
+
peak hours and the first sign anyone saw was a flood of slow-speed
|
|
9
|
+
complaints.
|
|
10
|
+
category: telecom
|
|
11
|
+
tags: [telecom, bandwidth, capacity, monitoring]
|
|
12
|
+
schedule: "*/15 * * * *"
|
|
13
|
+
timezone: "UTC"
|
|
14
|
+
runner: shell
|
|
15
|
+
command: >
|
|
16
|
+
util=$(snmpget -v2c -c "{{snmp_community}}" -Ovq "{{link_host}}" "{{snmp_oid}}" 2>/dev/null | tr -d '\r');
|
|
17
|
+
if [ -z "$util" ]; then echo "no SNMP response from {{link_host}} — check reachability/community string"; exit 0;
|
|
18
|
+
elif [ "${util%.*}" -ge "{{warn_threshold_pct}}" ]; then echo "WARNING: link {{link_host}} at ${util}% utilization (threshold {{warn_threshold_pct}}%)"; exit 1;
|
|
19
|
+
else echo "OK: link {{link_host}} at ${util}% utilization"; fi
|
|
20
|
+
variables:
|
|
21
|
+
link_host:
|
|
22
|
+
default: "10.0.0.1"
|
|
23
|
+
description: IP or hostname of the router/switch interface to poll.
|
|
24
|
+
snmp_community:
|
|
25
|
+
default: "public"
|
|
26
|
+
description: SNMP community string (or use SNMPv3 credentials via a wrapper script).
|
|
27
|
+
snmp_oid:
|
|
28
|
+
default: "1.3.6.1.2.1.31.1.1.1.6"
|
|
29
|
+
description: SNMP OID for the interface counter you're tracking utilization from.
|
|
30
|
+
warn_threshold_pct:
|
|
31
|
+
default: 85
|
|
32
|
+
description: Utilization percentage that triggers a warning.
|
|
33
|
+
compatible_agents: [generic, claude, codex]
|
|
34
|
+
notes: >
|
|
35
|
+
Requires `snmpget` (net-snmp) and a readable SNMP OID for the target
|
|
36
|
+
interface — the default OID is illustrative, replace with the correct
|
|
37
|
+
ifHCOutOctets/utilization OID for your gear. Read-only poll.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
id: peering-transit-contract-renewal-check
|
|
2
|
+
version: 1
|
|
3
|
+
name: Peering/Transit Contract Renewal Check
|
|
4
|
+
description: >
|
|
5
|
+
Checks upstream transit and peering agreements for upcoming renewal or
|
|
6
|
+
auto-renew deadlines and warns with enough lead time to renegotiate.
|
|
7
|
+
Use this if a transit contract has ever auto-renewed at last year's
|
|
8
|
+
rate (or worse) because nobody flagged the deadline until the invoice
|
|
9
|
+
changed.
|
|
10
|
+
category: telecom
|
|
11
|
+
tags: [telecom, peering, transit, contracts]
|
|
12
|
+
schedule: "0 7 * * 1"
|
|
13
|
+
timezone: "UTC"
|
|
14
|
+
runner: shell
|
|
15
|
+
command: >
|
|
16
|
+
awk -F',' -v warn_days="{{warn_days_before}}" '
|
|
17
|
+
NR==1 {next}
|
|
18
|
+
{
|
|
19
|
+
cmd = "date -d \"" $2 "\" +%s 2>/dev/null || date -j -f %Y-%m-%d \"" $2 "\" +%s 2>/dev/null";
|
|
20
|
+
cmd | getline renewal_epoch; close(cmd);
|
|
21
|
+
"date +%s" | getline now_epoch; close("date +%s");
|
|
22
|
+
diff_days = (renewal_epoch - now_epoch) / 86400;
|
|
23
|
+
if (diff_days <= warn_days && diff_days >= 0) {
|
|
24
|
+
printf "RENEWAL DUE: %s (%s) renews/auto-renews %s (%d days)\n", $1, $3, $2, diff_days;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
' "{{contracts_csv_path}}"
|
|
28
|
+
variables:
|
|
29
|
+
contracts_csv_path:
|
|
30
|
+
default: "./transit-peering-contracts.csv"
|
|
31
|
+
description: "Path to a CSV with columns: provider_name,renewal_date (YYYY-MM-DD),contract_type (transit/peering/IX)."
|
|
32
|
+
warn_days_before:
|
|
33
|
+
default: 60
|
|
34
|
+
description: Days before renewal date to start warning — transit renegotiation needs lead time.
|
|
35
|
+
compatible_agents: [generic, claude, codex]
|
|
36
|
+
notes: Assumes contract renewal dates are manually tracked or exported from a contracts log into the CSV.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
id: service-ticket-churn-risk-review
|
|
2
|
+
version: 1
|
|
3
|
+
name: Service Ticket Churn Risk Review
|
|
4
|
+
description: >
|
|
5
|
+
Reviews customers with repeated service tickets in a recent window and
|
|
6
|
+
drafts a churn-risk summary with recommended outreach. Use this if a
|
|
7
|
+
customer has ever quietly churned after their third outage ticket
|
|
8
|
+
because nobody connected the dots between separate complaints.
|
|
9
|
+
category: telecom
|
|
10
|
+
tags: [telecom, churn, support, retention]
|
|
11
|
+
schedule: "0 9 * * 1"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: hybrid
|
|
14
|
+
command: >
|
|
15
|
+
awk -F',' -v min_tickets="{{min_ticket_count}}" -v days="{{lookback_days}}" '
|
|
16
|
+
NR==1 {next}
|
|
17
|
+
{
|
|
18
|
+
cmd = "date -d \"" $2 "\" +%s 2>/dev/null || date -j -f %Y-%m-%d \"" $2 "\" +%s 2>/dev/null";
|
|
19
|
+
cmd | getline ticket_epoch; close(cmd);
|
|
20
|
+
"date +%s" | getline now_epoch; close("date +%s");
|
|
21
|
+
age_days = (now_epoch - ticket_epoch) / 86400;
|
|
22
|
+
if (age_days <= days) count[$1]++;
|
|
23
|
+
}
|
|
24
|
+
END {
|
|
25
|
+
for (c in count) if (count[c] >= min_tickets) printf "%s: %d tickets in last %d days\n", c, count[c], days;
|
|
26
|
+
}
|
|
27
|
+
' "{{tickets_csv_path}}"
|
|
28
|
+
prompt: |
|
|
29
|
+
Here is the customer's recent service ticket history: {{tickets_csv_path}}
|
|
30
|
+
(columns: customer,ticket_date,issue_summary). Customers with
|
|
31
|
+
{{min_ticket_count}}+ tickets in the last {{lookback_days}} days are at
|
|
32
|
+
elevated churn risk.
|
|
33
|
+
1. For each flagged customer, summarize the pattern of issues (repeat
|
|
34
|
+
outages, slow speeds, billing disputes, etc.).
|
|
35
|
+
2. Assess churn risk as low/medium/high based on ticket frequency and
|
|
36
|
+
issue severity.
|
|
37
|
+
3. Draft a short, specific outreach note (not generic) that account
|
|
38
|
+
management could send or use as a call script — reference the actual
|
|
39
|
+
issues so the customer feels heard, not processed.
|
|
40
|
+
script_note: >
|
|
41
|
+
The shell command gives you the raw list of customers who crossed the
|
|
42
|
+
ticket-count threshold — zero tokens, no interpretation. The prompt adds
|
|
43
|
+
issue-pattern synthesis and drafts the actual outreach message, which
|
|
44
|
+
needs judgment the script can't provide.
|
|
45
|
+
variables:
|
|
46
|
+
tickets_csv_path:
|
|
47
|
+
default: "./service-tickets.csv"
|
|
48
|
+
description: "Path to a CSV with columns: customer,ticket_date (YYYY-MM-DD),issue_summary."
|
|
49
|
+
min_ticket_count:
|
|
50
|
+
default: 3
|
|
51
|
+
description: Minimum tickets in the lookback window to flag as churn risk.
|
|
52
|
+
lookback_days:
|
|
53
|
+
default: 30
|
|
54
|
+
description: Rolling window, in days, to count tickets within.
|
|
55
|
+
compatible_agents: [claude, codex, hermes, generic]
|
|
56
|
+
notes: Read-only analysis — does not send anything, just prepares the flag list and draft outreach for a human to review and send.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
id: sla-uptime-breach-tracker
|
|
2
|
+
version: 1
|
|
3
|
+
name: SLA Uptime Breach Tracker
|
|
4
|
+
description: >
|
|
5
|
+
Compares each customer's measured monthly uptime percentage against
|
|
6
|
+
their contracted SLA and flags anyone below threshold. Use this if
|
|
7
|
+
you've ever missed an SLA credit obligation because nobody totaled up
|
|
8
|
+
the downtime minutes until the customer's lawyer did.
|
|
9
|
+
category: telecom
|
|
10
|
+
tags: [telecom, sla, uptime, contracts]
|
|
11
|
+
schedule: "0 6 1 * *"
|
|
12
|
+
timezone: "UTC"
|
|
13
|
+
runner: shell
|
|
14
|
+
command: >
|
|
15
|
+
awk -F',' -v default_sla="{{default_sla_pct}}" '
|
|
16
|
+
NR==1 {next}
|
|
17
|
+
{
|
|
18
|
+
customer=$1; measured=$2; contracted=$3;
|
|
19
|
+
if (contracted == "") contracted = default_sla;
|
|
20
|
+
if (measured+0 < contracted+0) {
|
|
21
|
+
printf "SLA BREACH: %s measured %.3f%% uptime, contracted %.3f%%\n", customer, measured, contracted;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
' "{{uptime_csv_path}}"
|
|
25
|
+
variables:
|
|
26
|
+
uptime_csv_path:
|
|
27
|
+
default: "./customer-uptime.csv"
|
|
28
|
+
description: "Path to a CSV with columns: customer,measured_uptime_pct,contracted_sla_pct (contracted column may be blank to use the default)."
|
|
29
|
+
default_sla_pct:
|
|
30
|
+
default: 99.9
|
|
31
|
+
description: Fallback contracted SLA percentage when a row doesn't specify one.
|
|
32
|
+
compatible_agents: [generic, claude, codex]
|
|
33
|
+
notes: >
|
|
34
|
+
Assumes measured uptime is exported monthly from your NMS/monitoring
|
|
35
|
+
platform into the CSV before this runs. Read-only — does not issue
|
|
36
|
+
SLA credits, just flags who owes one.
|
|
@@ -14,6 +14,7 @@ export const CATEGORY_DESCRIPTIONS = {
|
|
|
14
14
|
ecommerce: "Storefront ops — carts, stock, returns, reviews.",
|
|
15
15
|
education: "Classroom ops — grading, attendance, deadlines, permission slips.",
|
|
16
16
|
events: "Event planning — budget, RSVPs, staffing, vendors, day-of check-in.",
|
|
17
|
+
fieldservice: "Dispatch ops — tech ETAs, parts, warranty claims, maintenance contracts.",
|
|
17
18
|
finance: "Personal/business finance — budgets, invoices, taxes, subscriptions.",
|
|
18
19
|
fitness: "Gym/studio ops — memberships, class utilization, equipment.",
|
|
19
20
|
fleet: "Vehicle fleet compliance — maintenance, registration, licenses, fuel.",
|
|
@@ -37,13 +38,16 @@ export const CATEGORY_DESCRIPTIONS = {
|
|
|
37
38
|
personal: "Daily life reminders — bills, habits, meals, screen time.",
|
|
38
39
|
podcast: "Show ops — publish cadence, guests, sponsors, ratings.",
|
|
39
40
|
productivity: "Work habits — inbox, standups, focus, meetings, reports.",
|
|
41
|
+
publishing: "Book/print ops — manuscript deadlines, royalties, print runs, rights.",
|
|
40
42
|
realestate: "Property management — leases, rent, vacancy, inspections, tax.",
|
|
41
43
|
restaurant: "Kitchen/FOH ops — food cost, labor cost, waste, inspections.",
|
|
42
44
|
retail: "Store ops — till reconciliation, opening checklist, scheduling.",
|
|
43
45
|
sales: "Pipeline ops — leads, deals, quota, CRM sync.",
|
|
44
46
|
security: "Security posture — keys, certs, access, scans, firewalls.",
|
|
47
|
+
spa: "Salon/spa/wellness ops — no-shows, inventory, license renewals, membership churn.",
|
|
45
48
|
support: "Helpdesk ops — SLA, backlog, CSAT, agent workload.",
|
|
46
49
|
team: "Team ops — 1:1s, on-call, PTO, anniversaries.",
|
|
50
|
+
telecom: "ISP/telecom ops — outages, SLA uptime, circuit provisioning, churn.",
|
|
47
51
|
travel: "Trip logistics — flights, passports, visas, insurance, miles.",
|
|
48
52
|
veterinary: "Clinic ops for animals — vaccines, controlled substances, boarding.",
|
|
49
53
|
warehousing: "Warehouse ops — dock scheduling, pick/pack errors, climate control.",
|
|
@@ -11,6 +11,11 @@ export const ALLOWED_DUPLICATE_PAIRS = [
|
|
|
11
11
|
"labor-cost-percentage-watch",
|
|
12
12
|
"Same benchmark-against-sales pattern, different cost categories (food vs. labor) — intentionally parallel jobs, not a copy-paste duplicate.",
|
|
13
13
|
],
|
|
14
|
+
[
|
|
15
|
+
"warranty-claim-deadline-check",
|
|
16
|
+
"warranty-claim-expiry-check",
|
|
17
|
+
"Same deadline-check pattern, different domains — automotive repair-order warranty claims vs. HVAC/appliance manufacturer warranty claims.",
|
|
18
|
+
],
|
|
14
19
|
];
|
|
15
20
|
|
|
16
21
|
export function isAllowedPair(idA, idB) {
|