{"id":48542077,"url":"https://github.com/nathanpitman/360-feedback","last_synced_at":"2026-04-15T13:30:53.851Z","repository":{"id":346382868,"uuid":"1189476511","full_name":"nathanpitman/360-Feedback","owner":"nathanpitman","description":"Anonymous 360° feedback tool for iHasco. Responses are written directly to an Excel file in your O365 environment via Power Automate. Colleague names are never stored in this repo — they're passed as a URL parameter at link-share time. The form is deployed to an unguessable hashed URL on GitHub Pages.","archived":false,"fork":false,"pushed_at":"2026-03-23T17:54:55.000Z","size":122,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-24T13:17:14.154Z","etag":null,"topics":["claude-code","feedback"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nathanpitman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-23T11:08:06.000Z","updated_at":"2026-03-23T17:54:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nathanpitman/360-Feedback","commit_stats":null,"previous_names":["nathanpitman/360-feedback"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/nathanpitman/360-Feedback","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nathanpitman%2F360-Feedback","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nathanpitman%2F360-Feedback/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nathanpitman%2F360-Feedback/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nathanpitman%2F360-Feedback/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nathanpitman","download_url":"https://codeload.github.com/nathanpitman/360-Feedback/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nathanpitman%2F360-Feedback/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31540826,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"online","status_checked_at":"2026-04-08T02:00:06.127Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude-code","feedback"],"created_at":"2026-04-08T05:02:16.706Z","updated_at":"2026-04-08T05:02:19.675Z","avatar_url":"https://github.com/nathanpitman.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 360° Feedback Form\n\nAnonymous 360° feedback tool for iHasco. Responses are written directly to an Excel file in your O365 environment via Power Automate. Colleague names are never stored in this repo — they're encoded into a shareable link generated by the built-in link generator. The form is deployed to an unguessable hashed URL on GitHub Pages.\n\n---\n\n## How it works\n\n```\nHR admin visits the Generator:\n  https://you.github.io/360-feedback/{hash}/generate/\n\n       ↓  (enters names + link lifetime, clicks Generate)\n\nGets a shareable link with an encoded ?id= token:\n  https://you.github.io/360-feedback/{hash}/?id=eyJuIjpb...\n\n       ↓  (names and expiry window encoded in the token — never in source)\n\nColleague fills in the form on GitHub Pages\n  (link shows as expired if opened past its lifetime)\n\n       ↓  (POST to Power Automate webhook — URL injected at build time, not in repo)\n\nPower Automate writes a row to 360_feedback_dashboard.xlsx in your SharePoint/OneDrive\n```\n\nThe `{hash}` in the URL is derived from your Power Automate webhook URL at build time — unguessable from the outside, but stable unless you rotate the secret.\n\n---\n\n## Files in this repo\n\n| File | Purpose |\n|---|---|\n| `src/form-template.html` | The feedback form. Edit this to change questions or styling. Contains no secrets. |\n| `src/generate.html` | The link generator form. HR admins use this to create shareable `?id=` links. |\n| `src/expired.html` | Error page shown when a feedback link is past its lifetime. |\n| `power_automate_payload_reference.json` | Sample JSON payload. Paste into Power Automate's \"Generate from sample\" when building the flow. |\n| `360_feedback_dashboard.xlsx` | Excel template. Upload once to SharePoint or OneDrive. Responses write here. |\n| `.github/workflows/deploy.yml` | Build and deploy pipeline. Injects the webhook URL and publishes to GitHub Pages. |\n| `skills/360-feedback-deployer/SKILL.md` | Context skill for AI assistants continuing work on this project. |\n\n---\n\n## One-time setup\n\n### Step 1 — Upload the Excel template to SharePoint or OneDrive\n\n1. Upload `360_feedback_dashboard.xlsx` to a SharePoint document library or your OneDrive\n2. Note the **site/drive path** — you'll need it in Step 2\n3. Make sure the file stays at this location permanently — Power Automate will write to it by path\n\n\u003e The file contains a table named `FeedbackResponses`. Do not rename this table or its columns or the Power Automate flow will break.\n\n---\n\n### Step 2 — Build the Power Automate flow\n\n\u003e **Note:** Power Automate's Import Package requires a proprietary zip format. The flow must be built manually — it only takes about 5 minutes and has 3 steps.\n\n**2a. Create a new flow**\n\n1. Go to [make.powerautomate.com](https://make.powerautomate.com)\n2. **My Flows → + New flow → Instant cloud flow**\n3. Name it `360 Feedback Receiver`\n4. Choose trigger: **When an HTTP request is received** → Create\n\n**2b. Add a Parse JSON step**\n\n1. Click **+ New step** → search for `Parse JSON` → select it\n2. Set **Content** to `Body` from the trigger's dynamic content panel\n3. Click **Generate from sample** and paste the entire contents of `power_automate_payload_reference.json` from this repo\n4. Click Done — Power Automate will generate the schema automatically\n\n**2c. Add an Excel — Add a row into a table step**\n\n1. Click **+ New step** → search `Excel Online (Business)` → select **Add a row into a table**\n2. Fill in the fields:\n   - **Location**: select your SharePoint site or OneDrive\n   - **Document Library**: the library where you uploaded the Excel file\n   - **File**: browse to `360_feedback_dashboard.xlsx`\n   - **Table**: select `FeedbackResponses`\n3. Map each column to the matching field from the Parse JSON dynamic content:\n\n| Excel column | Dynamic content value |\n|---|---|\n| Timestamp | Use expression: `utcNow()` |\n| Subject Name | `subject_name` |\n| Form ID | `form_id` |\n| Authentic and ethical leadership | `authentic_ethical_leadership` |\n| Emotional intelligence | `emotional_intelligence` |\n| Inspire and influence | `inspire_and_influence` |\n| Change management | `change_management` |\n| Team building and collaboration | `team_building_collaboration` |\n| Future focused, innovative, curious and courageous | `future_focused_innovative` |\n| Decision making and problem solving | `decision_making_problem_solving` |\n| Growth mindset with high self-awareness | `growth_mindset` |\n| Cultural competence | `cultural_competence` |\n| Communicates with impact | `communicates_with_impact` |\n| Strengths | `strengths` |\n| Development Areas | `development` |\n\n\u003e `form_id` is the encoded token from the `?id=` URL parameter. All submissions from the same shared link carry the same `form_id`, making it easy to filter responses by session in Excel.\n\n**2d. Save and get your webhook URL**\n\n1. Click **Save**\n2. Go back to the **When an HTTP request is received** trigger step\n3. Copy the **HTTP POST URL** — this is your `PA_WEBHOOK_URL`\n4. Make sure the flow is **turned on** (flows default to off after creation)\n\n\u003e Keep this URL private. It is the only security layer between the public internet and your Excel file.\n\n---\n\n### Step 3 — Add the webhook URL as a GitHub secret\n\n1. In this repo, go to **Settings → Secrets and variables → Actions**\n2. Click **New repository secret**\n3. Set:\n   - **Name**: `PA_WEBHOOK_URL`\n   - **Value**: the full webhook URL from Step 2\n\n---\n\n### Step 4 — Enable GitHub Pages\n\n1. Go to **Settings → Pages**\n2. Set **Source** to: `Deploy from a branch`\n3. Set **Branch** to: `gh-pages` / `/ (root)`\n4. Save\n\n\u003e The `gh-pages` branch is created automatically on first deploy.\n\n---\n\n### Step 5 — Deploy\n\nEither push any change to `main`, or go to:\n\n**Actions → Deploy 360 Feedback Form → Run workflow → Run workflow**\n\nOnce complete, check the Actions log for your live URLs:\n\n```\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nGenerator URL: https://yourusername.github.io/360-feedback/a3f7c2d1e4b89f01/generate/\nForm base URL: https://yourusername.github.io/360-feedback/a3f7c2d1e4b89f01/\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n```\n\nBookmark the **Generator URL** and share it with HR admins.\n\n---\n\n## Sharing the form\n\nUse the **Generator** (`/{hash}/generate/`) to create feedback links:\n\n1. Enter the names of the people you're collecting feedback for\n2. Choose a link lifetime (7, 14, or 30 days)\n3. Click **Generate link** — a `?id=` encoded link is produced\n4. Copy and share the link with colleagues\n\nThe link encodes the colleague names and expiry window into a URL-safe token. Anyone opening the link after the lifetime window will see an expiry message and be asked to request a new link.\n\n---\n\n## Updating the form\n\nEdit `src/form-template.html` and push to `main`. The workflow redeploys automatically within ~1 minute.\n\n---\n\n## Rotating the webhook URL\n\nIf you ever need to invalidate the current URL (e.g. suspected abuse):\n\n1. In Power Automate, delete the HTTP trigger and re-add it — this generates a new URL\n2. Update the `PA_WEBHOOK_URL` secret in GitHub\n3. Push any change to `main` to trigger a redeploy\n4. The hashed path in the URL will change — share the new Generator URL from the Actions log\n\nOld links will 404 automatically.\n\n---\n\n## Troubleshooting\n\n| Symptom | Likely cause | Fix |\n|---|---|---|\n| Submissions don't appear in Excel | Flow is turned off | Go to Power Automate and turn the flow on |\n| Submissions don't appear in Excel | Excel table name changed | Ensure the table is named `FeedbackResponses` |\n| Submissions don't appear in Excel | Wrong file path in flow | Re-check the Drive and File fields in the Add Row action |\n| GitHub Pages shows 404 | Pages not configured | Check Settings → Pages → gh-pages branch |\n| Actions log shows secret not set | Secret missing | Add `PA_WEBHOOK_URL` in Settings → Secrets → Actions |\n| Form shows \"Invalid link\" or \"No colleagues in link\" | Missing or malformed `?id=` token | Use the Generator to create a new link |\n| Form redirects to expired page | Link lifetime has passed | Use the Generator to create a new link |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnathanpitman%2F360-feedback","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnathanpitman%2F360-feedback","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnathanpitman%2F360-feedback/lists"}