Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: Bug report
about: Something is broken or behaving unexpectedly
title: "As a [user/developer] I want to [fix] so I can [benefit]"
labels: "bug"
assignees: ""
---

## Summary

One paragraph describing what is broken and what the expected behaviour is.

## Priority

High / Medium / Low

## Steps to reproduce

1.
2.
3.

## Expected behaviour

<!-- What should happen. -->

## Actual behaviour

<!-- What actually happens. Include any error messages, console output, or screenshots. -->

## Acceptance criteria

- [ ]
- [ ]

## Out of scope

<!-- Explicit exclusions to prevent scope creep. -->

-
42 changes: 42 additions & 0 deletions .github/ISSUE_TEMPLATE/feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
name: Feature / improvement
about: Suggest a new feature or improvement
title: "As a [user/developer] I want to [action] so I can [benefit]"
labels: ""
assignees: ""
---

## Summary

One paragraph describing the problem and the goal.

## Priority

High / Medium / Low

## UI spec (Carbon g100)

<!-- Required for any UI changes. Use bullet points. Carbon hard rules apply:
sentence case labels, 0px border-radius on buttons/inputs/cards,
no emoji, IBM Plex everywhere, semantic tokens only. -->

-

## Data model

<!-- Required for any new or changed database tables. SQL schema snippet. -->

```sql

```

## Acceptance criteria

- [ ]
- [ ]

## Out of scope

<!-- Explicit exclusions to prevent scope creep. -->

-
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ All notable changes to Workout Lens are documented here.

## [Unreleased]

### Added
- **Open source housekeeping** — repository prepared for public release: added MIT `LICENSE`, `CONTRIBUTING.md`, and GitHub issue templates (feature + bug). `README.md` updated with contributing and license sections; instance-specific infrastructure IDs removed. `CLAUDE.md` stripped of internal deployment identifiers. `app/package.json` updated with `author`, `license`, and `repository` fields.

### Fixed
- **Gym class name deduplication** — `sportySync.js` now strips quoted annotations (e.g. `"SVART TRØYE"`) from class names before storing them, preventing duplicate filter chips in Report when sporty.no temporarily appends labels to existing class names. A one-time SQL migration cleaned all existing rows. Handles both straight (`"`) and curly (`"`) double quotes generically.

Expand Down
3 changes: 1 addition & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,7 @@ Rules of thumb when adding tests:
Coverage (`npm run test:ci`) is configured in `vite.config.js` to scope to `src/lib/**` and `api/claudeUtils.js`. Current line coverage: `utils.js` ~80%, `prompts.js` 100%, reducer & `calcMuscles` ~100% within tested files; `db.js` and `bodymap.jsx` SVG render code are intentionally untested.

## Azure deploy notes
- **Resource group:** `rg-muskelkart` (West Europe) — **Azure resource name:** `muskelkart`
- **Supabase Auth redirect URLs** — three entries in Authentication → URL Configuration → Additional redirect URLs: `http://localhost:4280` (local dev), `https://workout.umulig.org` + `https://workout.umulig.org/**` (prod), and `https://white-island-090dfd003-*.westeurope.7.azurestaticapps.net` (PR preview wildcard — safe because the `white-island-090dfd003` prefix is unique to this SWA instance). The app uses `emailRedirectTo: window.location.origin` so no per-PR config is needed (#135)
- **Supabase Auth redirect URLs** — add the following in Supabase → Authentication → URL Configuration → Additional redirect URLs: `http://localhost:4280` (local dev), your production URL + `<prod-url>/**` (prod), and `<your-swa-subdomain>-*.westeurope.7.azurestaticapps.net` (PR preview wildcard). The app uses `emailRedirectTo: window.location.origin` so no per-PR config is needed (#135)
- For secrets/settings/live URL, see README → Deployment section

## Known pitfalls (previously hit, fixed, must not regress)
Expand Down
82 changes: 82 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Contributing

Thanks for your interest in Workout Lens. This document covers everything you need to run the project locally and submit changes.

## Prerequisites

| Tool | Version | Notes |
|---|---|---|
| Node.js | 22.x LTS | Use [fnm](https://github.com/Schniz/fnm) or [nvm](https://github.com/nvm-sh/nvm) |
| Azure Static Web Apps CLI | latest | `npm install -g @azure/static-web-apps-cli` |

## One-time setup

```bash
# Install frontend dependencies
cd app && npm install

# Install API dependencies
cd api && npm install

# Copy and fill in the env files
cp app/.env.local.example app/.env.local # VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY
cp app/api/local.settings.json.example app/api/local.settings.json # ANTHROPIC_API_KEY, SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, VITE_SUPABASE_ANON_KEY, SUPABASE_ANON_KEY
```

You will need:
- A [Supabase](https://supabase.com) project with the schema from `supabase/migrations/`
- An [Anthropic](https://console.anthropic.com) API key

## Running locally

Start both the Vite dev server and the Azure SWA emulator:

```bash
# Terminal 1 — Vite
cd app && npm run dev

# Terminal 2 — SWA emulator (proxies /api/* to local Azure Functions)
swa start http://localhost:5173 --api-location app/api
```

Open **http://localhost:4280** — not port 5173. The API routes (`/api/claude`, `/api/sporty-sync`) only work through the SWA proxy.

> On Windows, a `dev.ps1` script can automate this. See the local development section in CLAUDE.md.

## Running tests

```bash
cd app
npm test # one-shot
npm run test:ci # one-shot with coverage
npm run test:watch # watch mode
```

The test suite is pure-logic (reducers, date helpers, validators, prompt builders, API guards) — no DOM, no live Supabase. It runs in under 2 seconds.

## Branch and commit conventions

| Branch type | Pattern | Example |
|---|---|---|
| Feature | `feat/<short-description>` | `feat/weekly-planner` |
| Bug fix | `fix/<short-description>` | `fix/history-date-parse` |
| Docs / chore | `docs/<topic>` or `chore/<topic>` | `docs/contributing` |

Commit messages follow the pattern: `type: description (#issue-number)`

Examples:
```
feat: add weekly training planner (#59)
fix: resolve muscle hover tooltip collision (#18)
docs: update CLAUDE.md for recommendation cache (#150)
```

## Submitting a pull request

1. Fork the repo and create a branch from `master`
2. Make your changes — keep scope tight and linked to one issue
3. Run `npm test` and confirm all tests pass
4. Open a PR against `master` with the issue number in the title
5. Fill in the PR template (Summary + test plan)

Issues use a structured format — see the issue templates in `.github/ISSUE_TEMPLATE/` or the issue format section in README.md.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Christopher Rotnes

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Add the following to Supabase **Authentication → URL Configuration → Additio
| URL | Purpose |
|---|---|
| `http://localhost:4280` | Local dev (SWA emulator) |
| `https://white-island-090dfd003-*.westeurope.7.azurestaticapps.net` | Azure SWA PR previews (wildcard covers all PR numbers) |
| `https://<your-swa-subdomain>-*.westeurope.7.azurestaticapps.net` | Azure SWA PR previews (wildcard covers all PR numbers) |

The app uses `emailRedirectTo: window.location.origin` so magic-link emails automatically point back to whichever environment the login was initiated from.

Expand Down Expand Up @@ -164,7 +164,7 @@ Live URL: `https://workout.umulig.org`
|---|---|
| `VITE_SUPABASE_URL` | Injected into frontend bundle via `env:` block on the build step |
| `VITE_SUPABASE_ANON_KEY` | Injected into frontend bundle via `env:` block on the build step |
| `AZURE_STATIC_WEB_APPS_API_TOKEN_WHITE_ISLAND_090DFD003` | Azure deploy token |
| `AZURE_STATIC_WEB_APPS_API_TOKEN_<YOUR_SWA_NAME>` | Azure deploy token (the exact name is generated by Azure when you create the SWA resource; find it in the deployment workflow Azure downloads to your repo) |

### Required app settings (Azure SWA)

Expand All @@ -178,6 +178,16 @@ Live URL: `https://workout.umulig.org`

> **Note:** The frontend is built in the GitHub Actions runner (not by Oryx inside Azure SWA's Docker container). Oryx strips `VITE_*` env vars before spawning Vite, so they would never reach the bundle if built there. The workflow pre-builds `app/dist/` and the Azure SWA action uploads it directly via `app_location: "app/dist"`. Do not revert this.

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for setup instructions, branch conventions, and how to submit a pull request.

## Backlog

Open work is tracked in [GitHub Issues](https://github.com/ChristopherRotnes/BodyMapTraining/issues).

## License

MIT — see [LICENSE](LICENSE).

IBM Plex fonts are licensed under the SIL Open Font License 1.1 — see [`app/public/fonts/LICENSE.txt`](app/public/fonts/LICENSE.txt).
8 changes: 7 additions & 1 deletion app/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
{
"name": "app",
"name": "workout-lens",
"private": true,
"version": "1.1.0-rc.1",
"author": "Christopher Rotnes",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/ChristopherRotnes/BodyMapTraining"
},
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
Loading