BikeControl (SwiftControl)
Use Zwift Click, Zwift Play, Shimano Di2, or any Bluetooth controller with MyWhoosh, Rouvy, Zwift, and more. Free to try on iOS, Android, Windows, and macOS.
Personal trainer in your pocket.
Translation pending
Sports & fitnessGo · Go TemplateGitHub @myrjolaOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Personal trainer app
Translation pending
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Petra is a minimalist, privacy-focused personal-trainer web app that generates
and tracks gym workouts. It plans a weekly schedule around the days you pick,
progresses weights and reps from your logged performance, and runs through a
complete mesocycle including deload weeks — for people who want guided
workouts rather than building their own programs.Read the full README ↗Petra is a minimalist, privacy-focused personal-trainer web app that generates and tracks gym workouts. It plans a weekly schedule around the days you pick, progresses weights and reps from your logged performance, and runs through a complete mesocycle including deload weeks — for people who want guided workouts rather than building their own programs.
Design stance, throughout:
The module is organised as a small platform/product monorepo:
internal/platform/ shared infrastructure, reusable by any app in the module
sqlitekit/ declarative SQLite migrator + Config-based NewDatabase (RO/RW split, optimizer, healthcheck)
auth/ passkey/WebAuthn handler, Store interface, auth.SchemaSQL
obs/ observability: logging, errorrecorder, flightrecorder, pprofserver
envstruct/ struct-tag environment-variable config
contexthelpers/ request-scoped context helpers
testkit/ shared test helpers
internal/petra/ the fitness product (domain / repository / service / notification)
repository/ owns schema.sql, fixtures.sql, and embed.go (SchemaSQL / FixturesSQL)
cmd/petra/ the Petra web app (owns its ui/templates + ui/static)
cmd/example/ a minimal todo CRUD app that proves the shared platform plumbing
internal/platform/ is generic and must stay product-agnostic; internal/petra/
is everything specific to the workout product. The split is enforced at lint time:
depguard rules forbid internal/platform/ from importing
internal/petra or cmd/, and forbid cmd/example/ from importing
internal/petra (it may only build on the shared platform).
cmd/example/ deliberately copies the web middleware/render boilerplate
rather than importing a shared web kit — see
ADR 0005.
make # install dependencies, configure linting
make setup-git-hooks # optional: pre-push gate for developing straight on main
make dev # start the server on a free local port and open the browser
You can attach a debugger to the running server.
When a feature spans multiple layers, work outwards from the data model; when a change is scoped to one layer, start there. Each layer has a README next to the code:
internal/petra/repository/ —
schema (schema.sql), migrations, SQL persistenceinternal/petra/domain/ — pure domain
logic and aggregate methodsinternal/petra/service/ —
cross-aggregate orchestration and external integrationscmd/petra/ — HTTP handlers, routing, error
handling, testingcmd/petra/ui/templates/ — templates
and CSS, with the visual language in
cmd/petra/ui/design-system.mdThe domain vocabulary — canonical terms and the aliases to avoid — lives in CONTEXT.md. Templates and static assets load from the filesystem at runtime, so the UI dev loop is edit → refresh, no rebuild.
make test # go test --race ./... (cached)
go test -v ./path/to/package -run TestName # single test
make ci # build + lint-fix + test; the pre-push gate
Petra is trunk-based: once make ci passes, push to main. Every push runs
make ci-full (adds shuffled tests + govulncheck) plus make migratetest
(restores the latest production backup and migrates it) in GitHub Actions,
deploys to staging, and promotes to production only when staging is healthy.
make ci is the fast local gate and deliberately skips the shuffle,
govulncheck, and migratetest that server CI adds — so a green make ci
can still fail the deploy gate. Before a risky push (test-ordering changes,
schema.sql/migrations, or go.mod bumps) run make ci-full locally —
and make migratetest for schema changes — to catch it on your machine.
Opening a PR instead provisions a production-like per-PR review app — useful
for infrastructure-level changes. Details in
docs/operations.md.
| Doc | Contents |
|---|---|
CONTEXT.md | Ubiquitous language of the workout domain |
docs/operations.md | Fly.io ops: database access, profiling, CI/CD, deployments |
docs/disaster-recovery.md | DR runbook: scenario catalog, rebuild from nothing |
docs/adr/ | Architecture decision records |
docs/ops-log/ | Dated records of manual prod surgery |
| Layer READMEs (above) | Per-layer architecture and conventions |
tlaplus/README.md | TLA+ models of the navigation shim |
secrets/README.md | Age-encrypted backup of app secrets |
Petra logo made by Martin Yrjölä using Inkscape.