Skip to content

Latest commit

 

History

History
184 lines (126 loc) · 6.5 KB

File metadata and controls

184 lines (126 loc) · 6.5 KB

Maintenance Guide — ShackDesk Backend

Cloudflare API Token

The CF_API_TOKEN GitHub Actions secret authorises Wrangler to deploy Workers.

To rotate:

  1. Cloudflare Dashboard → My Profile → API Tokens → Create Token
  2. Use the Edit Cloudflare Workers template
  3. Add D1 write permission if not included
  4. Copy the token
  5. GitHub → Computer-Consultant/ShackDesk-BackendSettings → Secrets → Actions
  6. Update CF_API_TOKEN
  7. Delete the old token from the Cloudflare dashboard

CF_ACCOUNT_ID is not a secret but is stored as a GitHub secret for convenience. Find it on the Cloudflare dashboard right sidebar of any zone page.

D1 Database

Database name: shackdesk-telemetry Database ID: e77c8a3d-cba7-4326-846c-faeb2c585da0

Viewing telemetry data

There are two options for querying data without building a dashboard:


Option 1 — Wrangler CLI

Run SQL queries directly from the terminal. Best for ad-hoc lookups and one-off investigations.

# Most recent 20 reports
wrangler d1 execute shackdesk-telemetry --remote \
  --command="SELECT * FROM reports ORDER BY received_at DESC LIMIT 20;"

# All crash events
wrangler d1 execute shackdesk-telemetry --remote \
  --command="SELECT id, app, version, os, props, received_at FROM reports WHERE event = 'crash' ORDER BY received_at DESC;"

# Crash count by app version
wrangler d1 execute shackdesk-telemetry --remote \
  --command="SELECT app, version, COUNT(*) as crashes FROM reports WHERE event = 'crash' GROUP BY app, version ORDER BY crashes DESC;"

# Event breakdown by app
wrangler d1 execute shackdesk-telemetry --remote \
  --command="SELECT app, event, COUNT(*) as total FROM reports GROUP BY app, event ORDER BY app, total DESC;"

# Reports from the last 7 days
wrangler d1 execute shackdesk-telemetry --remote \
  --command="SELECT * FROM reports WHERE received_at > datetime('now', '-7 days') ORDER BY received_at DESC;"

# OS version distribution
wrangler d1 execute shackdesk-telemetry --remote \
  --command="SELECT os, COUNT(*) as total FROM reports GROUP BY os ORDER BY total DESC;"

Option 2 — Cloudflare D1 Studio (web UI)

A built-in SQL console in the Cloudflare dashboard — no setup required.

  1. Cloudflare Dashboard → Workers & Pages → D1
  2. Click shackdesk-telemetry
  3. Click the Console tab
  4. Type and run any SQL query directly in the browser

D1 Studio supports the same queries as the CLI above. Results are displayed as a table. Useful for quick browsing without opening a terminal.


Option 3 — Analytics dashboard (planned)

The Reports Worker in workers/reports/ serves an authenticated web UI with aggregate views, recent reports, filters, report detail, event totals, known installs, total runs, and crash counts by app/version. It queries D1 directly and uses HTTP Basic Auth.

Total runs are counted from app_start events. Known installs are counted from distinct anonymous install identifiers in props, using common keys such as install_id, installation_id, installId, installationId, client_id, clientId, anonymous_id, anonymousId, support_id, or supportId.

Reports Worker routes:

  • GET / - private HTML dashboard
  • GET /api/summary - aggregate counts and breakdowns
  • GET /api/options - distinct filter values
  • GET /api/reports - filtered report rows
  • GET /api/reports/:id - single report detail

All Reports Worker API routes are read-only.


Query the database

wrangler d1 execute shackdesk-telemetry --remote --command="SELECT * FROM reports ORDER BY received_at DESC LIMIT 20;"

Data retention — manual purge (90-day policy)

wrangler d1 execute shackdesk-telemetry --remote \
  --command="DELETE FROM reports WHERE received_at < datetime('now', '-90 days');"

This should be run periodically. Automating it via a Cloudflare Cron Trigger is a future improvement.

Schema migrations

Schema changes require a migration file. Never alter the live schema directly without testing locally first.

  1. Write the migration SQL
  2. Test locally: wrangler d1 execute shackdesk-telemetry --local --file=migration.sql
  3. Apply to production: wrangler d1 execute shackdesk-telemetry --remote --file=migration.sql
  4. Commit the migration file to the repo under db/migrations/

Adding a New Worker

  1. Create workers/<name>/src/index.js
  2. Add a new [[routes]] block and any bindings to wrangler.toml
  3. If the new Worker needs its own D1 database, create it: wrangler d1 create <db-name>
  4. Add a deploy step to .github/workflows/deploy.yml if it needs a separate pipeline

Reports Worker Setup

The Reports Worker has a separate Wrangler config:

wrangler deploy --config wrangler.reports.toml

Set the Basic Auth credentials as Cloudflare Worker secrets:

wrangler secret put REPORTS_USERNAME --config wrangler.reports.toml
wrangler secret put REPORTS_PASSWORD --config wrangler.reports.toml

Do not store these values in the repo.

The reports.shackdesk.com DNS record must be proxied in Cloudflare. Wrangler registers the Worker route from wrangler.reports.toml during deployment.

Local Development

wrangler dev

Wrangler creates a local SQLite database at .wrangler/state/. This is gitignored.

To seed the local database with the schema:

wrangler d1 execute shackdesk-telemetry --local --file=db/schema.sql

DNS

telemetry.shackdesk.com — CNAME record in the Cloudflare zone, proxied (orange cloud). Wrangler registers the route automatically on deploy via wrangler.toml. If the route ever disappears, redeploy: wrangler deploy.

Cloudflare Rate Limiting

Rate limiting is not in code — it is configured in the Cloudflare dashboard.

Location: Cloudflare Dashboard → shackdesk.com zone → Security → WAF → Rate Limiting Rules

Free tier limit: 1 rule per account (not per zone). The current rule is scoped to the /report path. If additional Workers or routes are added in the future, consider updating the rule expression to match the entire telemetry.shackdesk.com hostname instead:

  • Broader expression: http.host eq "telemetry.shackdesk.com"

This covers all current and future routes on that subdomain without needing additional rules. If Workers on other subdomains also need rate limiting, combine them with or in the same rule, or upgrade to Pro (5 rules).

Current rule:

  • Expression: http.request.uri.path eq "/report"
  • Threshold: 10 requests per 10 seconds per IP (free tier minimum window)
  • Action: Block for 10 seconds