Our review
Downloads and analyzes a ConnectStats bug report to extract logs, metadata, and databases for issue investigation.
Strengths
- Automates full extraction and analysis of the bug report
- Leverages design docs to understand schemas
- Examines log files, SQLite databases, and settings
- Identifies errors and patterns in logs
Limitations
- Requires CS_PASSWORD environment variable and tools (jq, unzip)
- Specific to ConnectStats application
- Results may require domain expertise to interpret
When a user provides a ConnectStats bug report ID to diagnose an issue.
For generic bugs not related to ConnectStats or without a valid bug report ID.
Security analysis
CautionThe skill downloads and analyzes bug reports using authenticated API calls and extracts zip files, which is powerful but legitimate. No destructive or exfiltrating actions are instructed. Caution rating due to network and file operations.
- •Uses curl with authentication to download data from external server
- •Extracts zip file with unzip
- •Runs sqlite3 on downloaded database files
Examples
/bugreport 142name: bugreport description: Download and analyze a ConnectStats bug report. Use when user provides a bugreport ID or says "bugreport", "bug report", "look at bug", etc. allowed-tools: Read, Grep, Glob, Edit, Write, Task, Bash, WebFetch
ConnectStats Bug Report Analyzer
Download a bug report from the ConnectStats server, extract it, parse the logs and user description, and start investigating the issue.
Prerequisites
CS_PASSWORDenvironment variable must be set (or will be prompted)jqandunzipmust be available- The connectstats project should be the current working directory
When Invoked
Arguments
- bugreport ID (required): numeric ID of the bug report (e.g.,
/bugreport 142)
Workflow
Step 1: Load context from design docs
Before diving in, load the relevant design docs to understand schemas and architecture:
# App-side database schema (activities_bugreport.db, track_*.db)
get_design_doc(library="connectstats", topic="database-schema")
# Server-side bugreport system and data model
get_design_doc(library="connectstats_server", topic="bugreport")
# If investigating data issues, also load:
get_design_doc(library="connectstats", topic="data-model")
get_design_doc(library="connectstats", topic="activity-types")
# If investigating server-side storage or FIT files:
get_design_doc(library="connectstats_server", topic="storage")
get_design_doc(library="connectstats_server", topic="api-endpoints")
Step 2: Create working directory and download
# Create a working directory for this bug report
mkdir -p /tmp/bugreport_{id}
cd /tmp/bugreport_{id}
# Download the JSON metadata
curl -s -u brice:${CS_PASSWORD} "https://connectstats.app/prod/bugreport/export?id={id}" | jq . > bugreport_meta.json
# Download the zip
curl -s -o bugreport_{id}.zip -u brice:${CS_PASSWORD} "https://connectstats.app/prod/bugreport/export?id={id}&zip"
# Extract it
unzip -o bugreport_{id}.zip
Step 3: Read and summarize the bug report metadata
Read bugreport_meta.json and present a summary:
- User description (the
descriptionfield - this is what the user reported) - App version (
version) - Device (
platformString) - OS (
systemName/systemVersion) - Date (
updatetime) - Email (
email- if provided) - Common ID (
commonid- links related reports)
Step 4: Parse the log file
Read bugreport.log. The log format is:
YYYY-MM-DD HH:MM:SS.sss pid LEVEL:filename:line:method; message
Where LEVEL is one of: INFO, ERR , WARN
Focus on:
- ERR lines - these are errors, show them prominently
- WARN lines - warnings that may be relevant
- Patterns - repeated errors, error sequences, timing of errors relative to user actions
- Look for common issues: type mapping failures, network errors, database errors, parsing failures
Step 5: Check other files in the zip
The zip may contain:
bugreport.log- app logs (always present)activities_bugreport.db- SQLite database of user's activities (same schema as main db — seeconnectstats:database-schemadesign doc)track_*.db- track database for the current activity (GPS points, HR, power, etc.)settings_bugreport.json/settings_bugreport.plist- app settingsmissing_fields.json- fields the app couldn't parseerror_last_search_cs_*.json- cached error responses from server
List what files were extracted and note which ones are available for deeper investigation.
Step 6: Query the app databases
Use the schema from the connectstats:database-schema design doc to write queries. Start with these diagnostics:
activities_bugreport.db (app-side SQLite):
# Activity count and types
sqlite3 activities_bugreport.db "SELECT activityType, COUNT(*) FROM gc_activities GROUP BY activityType ORDER BY COUNT(*) DESC;"
# Recent activities
sqlite3 activities_bugreport.db "SELECT activityId, activityType, datetime(BeginTimestamp, 'unixepoch') as date, SumDistance, SumDuration FROM gc_activities ORDER BY BeginTimestamp DESC LIMIT 20;"
# Check for NULL values (NaN persisted as NULL — a known bug pattern)
sqlite3 activities_bugreport.db "SELECT a.activityId, a.activityType, v.field, v.value, v.uom FROM gc_activities a JOIN gc_activities_values v ON a.activityId = v.activityId WHERE v.value IS NULL LIMIT 20;"
# Check summary values for a specific activity
sqlite3 activities_bugreport.db "SELECT field, value, uom FROM gc_activities_values WHERE activityId = '{activityId}' ORDER BY field;"
track_*.db (per-activity trackpoint data):
# Count trackpoints
sqlite3 track_{activityId}.db "SELECT COUNT(*) FROM gc_track;"
# Sample trackpoints
sqlite3 track_{activityId}.db "SELECT * FROM gc_track LIMIT 5;"
# Check laps
sqlite3 track_{activityId}.db "SELECT * FROM gc_laps;"
# Check extra fields
sqlite3 track_{activityId}.db "SELECT DISTINCT field FROM gc_track_extra;" 2>/dev/null
Step 7: Initial analysis
Based on the user's description and the log errors:
- Summarize what the user is experiencing
- Identify the most likely area of code involved (use source file:line references from the log)
- If there are ERR lines, map them to source code in the connectstats project
- Cross-reference database findings with log errors
- If
missing_fields.jsonexists, check for field mapping issues - If error JSON files exist, check for server-side issues
Step 8: Start investigating
Using the connectstats project source code:
- Look up the source files referenced in error log lines
- Cross-reference with design docs (use
list_libraries/get_design_doc) - Propose hypotheses for the root cause
- Suggest next steps for debugging
Output Format
Present findings as:
## Bug Report #{id}
### User Report
> {description from the user}
### Environment
- Device: {platformString}
- OS: {systemName} {systemVersion}
- App: {applicationName} {version}
- Date: {updatetime}
### Log Analysis
**Errors found: {count}**
{list of ERR lines with source references}
**Warnings: {count}**
{summary of WARN lines if relevant}
### Files Available
{list of extracted files}
### Database Summary
{activity counts, types, any anomalies found}
### Initial Assessment
{analysis connecting user description to log evidence}
### Hypotheses
1. {most likely cause}
2. {alternative cause}
### Next Steps
- {suggested investigation steps}
Fetching Server-Side Data
The bugreport only contains the app-side snapshot. When you need server-side data, ask the user to fetch it. The server project is at ~/Developer/public/connectstats_server — see the connectstats_server design docs for full details.
Get raw activity JSON from server
Ask the user to run on the server:
php setup/debugdata.php {activity_id}
This dumps the raw Garmin JSON the server stored for the activity — shows original field names and values before any app-side mapping. Useful when the app-side type mapping or field parsing is suspect.
Fetch a FIT file from S3
FIT files are stored in S3 (see connectstats_server:storage design doc). The S3 path follows the pattern:
assets/users/{cs_user_id}/{fileType}/{file_id}.{fileType}
Ask the user to retrieve the FIT file from S3 for the activity in question. The file_id can be found in the server's activities or fitfiles table. Once downloaded, you can parse it with the FitFileParser library (see FitFileParser design docs).
FIT files downloaded by the app are saved locally as:
track_cs_{serviceActivityId}.fit(from ConnectStats server)track_csalt_{externalActivityId}.fit(from Garmin fallback)
Check the admin web interface
The server has a bugreport viewer at bugreport/list.php?id={id} which shows:
- Color-coded log output with links to GitHub source lines
- Links to open
.dbfiles in phpliteadmin - Related reports by commonid
Server API endpoints
See connectstats_server:api-endpoints design doc for the full API. Key endpoints for debugging:
api/connectstats/search— activity search (paginated, returns Garmin JSON as-is)api/connectstats/file— FIT file download (by activity_id)api/connectstats/json— activity detail/weather data
Common Bug Patterns
Silent activity drops (no data for certain activity types)
- Symptom: User reports missing activities, log shows no errors
- Cause: Activity type mapping returns nil in
GCActivityTypes.m:activityTypeForConnectStatsType: - Check: Look at
error_last_search_cs_*.jsonfor the rawactivityTypestrings from Garmin - Investigation: The Garmin API periodically changes type strings (e.g., dropped
_SNOWBOARDING_WSsuffix). WhenchangeActivityType:nilis called, the activity import is silently skipped (GCActivity+Import.mguard clause). Seeconnectstats:activity-typesdesign doc.
NaN/missing summary values
- Symptom: User sees "nan" for power, HR, speed, or other metrics
- Cause: Incomplete FIT SESSION messages create GCActivitySummaryValue with NaN, which overwrites valid server data and persists as NULL in SQLite
- Check:
SELECT field, value FROM gc_activities_values WHERE activityId = 'X' AND value IS NULL; - Investigation: Track database may have valid data in
gc_trackrecords even when summary is NaN. Fetch the FIT file from S3 to inspect SESSION vs RECORD messages.
FIT file re-download loop
- Symptom: High bandwidth usage, repeated download attempts in log
- Cause: Unparseable FIT file with no empty track DB created to mark completion
- Check: Look for repeated
FIT data could not be parsedwarnings for the same activity
Database errors
- Symptom: ERR lines with "DB error" or "DB Error" in log
- Check: Schema migrations in
GCActivity+Database.m:ensureDbStructure:. Seeconnectstats:database-schemadesign doc for the full schema and migration history.
Tips
- The
commonidfield links related bug reports from the same user — if non-empty and not "-1", there may be earlier reports worth checking - Log source references like
GCActivity.m:425map toConnectStats/src/GCActivity.mline 425 - Settings JSON can reveal user configuration that might trigger edge cases (e.g., which services are enabled, metric vs imperial)
- Error JSON files contain raw server responses that failed to parse — check the
activityTypefield values - When the bugreport db doesn't have enough info, ask the user to run server-side debug scripts or fetch data from S3
- The server is type-agnostic — it stores raw Garmin JSON and returns it as-is. All type mapping happens app-side.
downloadMethodin gc_activities tells you how far the download got: 0=search list only, 1=activity details fetched, 2=FIT file downloaded and parsed
Next.js App Router Expert
Development
A skill that turns Claude into a Next.js App Router expert.
README Generator
Development
Creates professional and comprehensive README.md files for your projects.
API Documentation Writer
Development
Generates comprehensive API documentation in OpenAPI/Swagger format.