Files
Project-SDE-WP-Suite/DEPLOYMENT.md
n.siegfried 3d4402c88c Switch feedback reverse proxy from IIS to NGINX
- Add nginx-wp-suite.conf: static site + /api/feedback proxy to the Power
  Automate trigger (SNI on, Host header, POST-only, body cap)
- Remove IIS web.config
- Update feedback-config.js comment and DEPLOYMENT.md to the NGINX setup

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 10:46:35 -07:00

6.2 KiB

Deployment & Feedback Collection

The Work Package Suite is a static client-side app — plain HTML, CSS, and JavaScript. There is no build step and no database.

Hosting it behind the firewall

Copy the whole folder to any internal web server and serve it over HTTP(S):

  • IIS / Apache / nginx — drop the files in the site root. index.html is the entry point.
  • SharePoint / network share — works too, as long as the files are served over http(s):// (not opened as file://...). Serving over HTTP makes localStorage and the embedded Work Package Creator (an <iframe>) behave reliably.

The app makes no outbound internet calls — the logo and all scripts are local, and the previous Google-Fonts dependency has been removed (fonts now fall back to system UI fonts). So it runs fully air-gapped behind a corporate firewall.

Where data lives

By default everything is stored in each user's own browser (localStorage): the SOP configuration, the saved Work Packages, the usage logs, and all feedback / comments. This means:

  • Data is per-user and per-device — it is not shared between people, and clearing browser data erases it.
  • Nothing is transmitted anywhere unless you enable central collection (below).

Feedback collection

There are two layers, and they work together.

1. Export / Import (no server required — works today)

Every feedback surface has Export and Import buttons:

  • Home page → Leave Feedback panel
  • SOP Configuration → Step Comments (header button)
  • Work Package Creator → Comments drawer

A reviewer clicks Export to download a JSON file and sends it to you; you click Import on your machine to merge everyone's feedback together (imports de-duplicate, so re-importing is safe). This needs zero infrastructure and works behind any firewall.

2. Central auto-collection (optional — flip on when hosting is known)

To also gather every submission automatically into one place, set a single value in feedback-config.js:

window.FEEDBACK_ENDPOINT = 'https://your-endpoint-url';

When set, each submission is additionally POSTed as JSON to that URL (saving locally still happens, so a failed/disabled endpoint never loses feedback). The endpoint can be either of:

Option A — a small backend on your host

Any server that can run code and append the request body to a file you can download. Example (Node/Express):

const express = require('express');
const fs = require('fs');
const app = express();
app.use(express.json());
app.post('/feedback', (req, res) => {
  fs.appendFileSync('feedback.jsonl', JSON.stringify(req.body) + '\n');
  res.sendStatus(204);
});
app.listen(8080);

Each line of feedback.jsonl is one submission; download it anytime. (PHP/ Python/ASP.NET equivalents are a few lines too.)

Option B — Internal NGINX reverse proxy → Power Automate (the chosen setup)

The browser posts to a same-origin path /api/feedback; NGINX forwards that to the Power Automate trigger. This avoids CORS entirely and keeps the secret trigger URL off the client. FEEDBACK_ENDPOINT is already set to /api/feedback, and nginx-wp-suite.conf contains the full server block.

On the NGINX box (one-time, server admin):

  1. Copy the project files to the web root (e.g. /var/www/wp-suite).
  2. Install nginx-wp-suite.conf (e.g. into /etc/nginx/conf.d/), and set server_name, the ssl_certificate paths (internal cert), and the root.
  3. In the location = /api/feedback block, replace the proxy_pass URL and the Host header with your real trigger URL / region host (keep the full query string incl. sig=).
  4. sudo nginx -t && sudo systemctl reload nginx.

Two NGINX details that matter: proxy_ssl_server_name on; (SNI is required for *.logic.azure.com or the TLS handshake fails) and the Host header set to the Azure region host. Both are already in the provided config.

In Power Automate:

  1. Create a flow with the "When an HTTP request is received" trigger.

  2. Set its Request Body JSON Schema to:

    {
      "type": "object",
      "properties": {
        "app":         { "type": "string" },
        "page":        { "type": "string" },
        "submittedAt": { "type": "string" },
        "type":        { "type": "string" },
        "name":        { "type": "string" },
        "author":      { "type": "string" },
        "text":        { "type": "string" },
        "step":        { "type": "integer" },
        "view":        { "type": "string" },
        "timestamp":   { "type": "string" },
        "ts":          { "type": "string" },
        "id":          { "type": "string" },
        "clientId":    { "type": "string" }
      }
    }
    

    name is used by the home/SOP forms, author by the Work Package Creator. Map both into one "Submitted by" column with an expression like coalesce(triggerBody()?['name'], triggerBody()?['author']).

  3. Add an action — Create item (SharePoint list) or Add a row into a table (Excel / Dataverse) — mapping the fields above.

  4. Save; copy the generated HTTP POST URL into web.config (POWER_AUTOMATE_TRIGGER_URL).

  5. A Power App (or just the list/Excel) reads that store to show live comments.

Chain: browser → /api/feedback (NGINX proxy) → Power Automate → SharePoint/Dataverse → Power App.

The "downloadable file" is then just the Excel/SharePoint list, viewable live or exported — all inside your corporate cloud.

CORS note

If the endpoint is on a different origin than the site, it must return CORS headers allowing the site's origin (e.g. Access-Control-Allow-Origin: https://wp-suite.yourcompany.local). A Power Automate HTTP trigger and a same-host backend both handle this cleanly; a same-origin backend needs no CORS at all.

Feedback payload shape

Each POST body looks like:

{
  "app": "Work Package Suite",
  "page": "/work-package-suite.html",
  "submittedAt": "2026-06-15T18:20:00.000Z",
  "type": "sop_step_comment",
  "name": "J. Park",
  "text": "Consider adding a fiber WP type",
  "step": 4
}

type is one of home_feedback, sop_step_comment, or wp_review_comment.