@wral/report-it 0.1.4 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -36,6 +36,8 @@ Keep this first in the host page's `<head>`:
36
36
  | --- | --- | --- | --- |
37
37
  | `api` | attribute | `https://api.wral.com/forms` | api-forms base URL (dev: `https://api.wral.com/dev/forms`) |
38
38
  | `client` | property | — | Full I/O surface override (API + auth); wins over `api`. See `src/demo/demo-client.mjs` for the shape |
39
+ | `facts-api` | attribute | — | api-user-facts v1 base (e.g. `https://api.wral.com/user-facts/v1`). Unset, a new account is never offered to save its details |
40
+ | `flow` | attribute | — | Open one form directly by its `formId` (e.g. `investigates`). The host page's `?flow=<formId>` does the same; the attribute wins |
39
41
 
40
42
  Styling hooks: design tokens are read as `var(--wral-…, fallback)` with
41
43
  prototype-accurate fallbacks, so the component renders correctly with no
@@ -44,7 +46,8 @@ column width (default 680px).
44
46
 
45
47
  ## How a submission flows
46
48
 
47
- 1. `GET {api}/v1/forms` (public) — one button per published form.
49
+ 1. `GET {api}/v1/forms` (public) — one button per published form
50
+ (forms with `listed: false` are served but not shown; see below).
48
51
  2. The chosen form's tree walks client-side: `choice` chips, `collect`
49
52
  cards (text/textarea/url/datetime/location/media/consent/select),
50
53
  the `gate` (My WRAL email + one-time code — skipped with a
@@ -56,6 +59,62 @@ column width (default 680px).
56
59
  `PUT /v1/requests/{requestId}` (idempotent — retries return the same
57
60
  reference) → confirmation + behind-the-scenes journey.
58
61
 
62
+ ### Hand-offs, unlisted forms and deep links (DEV-1305)
63
+
64
+ A choice option may carry `form` (and optionally `path`) instead of
65
+ `next`: choosing it switches to that form document and replays the
66
+ `path` choice steps there first. News → "5 On Your Side" lands on the
67
+ consumer form's complaint card, past its own "5 On Your Side or
68
+ Investigates?" question. The submission is made against the target
69
+ form, with the preset steps at the head of its `path`; a path through
70
+ a hand-off option itself is never sent (the API rejects one).
71
+
72
+ The form the viewer came from is kept as an origin (`src/lib/handoff.mjs`),
73
+ persisted with the draft: the transcript reads as one conversation, a
74
+ reload rebuilds it, and **Back** from the first card after a hand-off
75
+ returns to the choice that made it, skipping the preset steps. A
76
+ hand-off to a form that is not loaded shows the load-error notice and
77
+ stays put.
78
+
79
+ An unlisted form (`listed: false`, e.g. `investigates`) is fetched with
80
+ the rest and reachable by hand-off or deep link, just not offered on the
81
+ entry screen. `?flow=<formId>` on the host page (or the `flow`
82
+ attribute) opens a form directly; a draft for that form (or one handed
83
+ off to or from it) resumes instead, and a draft for any other form
84
+ yields to the link.
85
+
86
+ ### Fields
87
+
88
+ - `text` fields pass `inputMode` and `autocomplete` from the form
89
+ document through to the input, and each collect card is a real
90
+ `<form autocomplete="on">`, so the browser can fill name, phone,
91
+ address and zip from the viewer's saved details. Nothing is prefilled
92
+ from My WRAL or stored anywhere else. (Autofill inside shadow DOM
93
+ varies by browser — verify on iOS Safari and Android Chrome.)
94
+ - A `text` field's `pattern` is checked before submit the way the
95
+ server checks it (a zip gets its own message).
96
+ - `consent` copy comes from the field's `text`. With
97
+ `requiredIf: "media"` the checkbox appears only once a file is
98
+ attached, is required only then, and is not sent without files.
99
+
100
+ ### Saving details to a new account
101
+
102
+ Off unless the host sets `facts-api` to an api-user-facts v1 base, e.g.
103
+ `<wral-report-it api="…" facts-api="https://api.wral.com/user-facts/v1">`.
104
+ With it set, when the sign-in card created the viewer's My WRAL account
105
+ on this page load, a successful submit adds one more step before the
106
+ confirmation: an offer to save their answers as user facts (the store
107
+ the audience dashboard reads). The confirmation shows only after
108
+ **Save to my account** succeeds or **No thanks**.
109
+ Only the `name` field (as `preferred_name`, at most 100 characters) and
110
+ the `postal-code` field (as `zipcode`, first five digits) are saved,
111
+ matched by `autocomplete` (`src/lib/user-facts.mjs`). Nothing is saved
112
+ without the viewer's click, for an existing account, or for an anonymous
113
+ report. A save clears the dashboard's `wral_user_facts` cache. A reload
114
+ between sign-in and submit drops the offer. In the demo,
115
+ `?demoexisting=1` makes accounts existing and `?demofactsfail=1` fails
116
+ the first save.
117
+
59
118
  ### Skipping the account (DEV-1270)
60
119
 
61
120
  The sign-in card files its alternatives under a collapsed **"Other ways
@@ -92,7 +151,11 @@ in place instead of opening the sign-in card.
92
151
 
93
152
  Auth uses `@wral/sdk-auth-audience` directly (`sendCode`/`verifyCode`);
94
153
  `requireAuth`/`authFetch` are deliberately avoided — their 401 paths
95
- redirect to `/login/`, which would destroy an unsubmitted form. A 401
154
+ redirect to `/login/`, which would destroy an unsubmitted form. The
155
+ bearer on uploads and submit is the viewer's Cognito **ID token** (not
156
+ the access token the SDK's `getAuthHeaders` sends): same `sub`, but it
157
+ also carries the verified `email`, which api-forms writes onto the
158
+ record beside the account id (`src/lib/id-token.mjs`). A 401
96
159
  mid-submit re-opens the gate in place and resumes where it parked.
97
160
 
98
161
  ## Drafts
@@ -115,7 +178,10 @@ npm run dev # vite harness at http://localhost:5173
115
178
 
116
179
  The harness runs against the live dev API by default (real My WRAL
117
180
  login — your email receives a real code) or fully offline with the
118
- in-memory demo client (any email, any six digits). Append
181
+ in-memory demo client (any email, any six digits). The demo client
182
+ serves the form documents in `src/demo/fixtures/` (copies of api-forms'
183
+ seeds), so hand-offs, `?flow=investigates` and the files-only consent
184
+ all work offline. Append
119
185
  `?demofail=1` to make the second upload fail once and exercise the
120
186
  retry UX. The **Anonymous route** checkbox (demo mode only, also
121
187
  settable with `?anon=1`) makes the demo client advertise anonymous
@@ -134,6 +200,25 @@ Repo variables: `NPM_TOKEN`, `AWS_ACCESS_KEY_ID`,
134
200
  `S3_BUCKET=cdn.wral.com`, `S3_PREFIX=@wral/report-it`,
135
201
  `AWS_DISTRIBUTION_ID`.
136
202
 
203
+ ## Staging pages
204
+
205
+ Both load the component from the CDN `latest` alias, so a release reaches
206
+ them without a republish. Each is a staging.wral.com publication whose
207
+ template is an HTML asset in the editorial DAM (`content: {}`,
208
+ `template: {"$ref": "https://assets.wral.com/<asset id>"}`):
209
+
210
+ | Page | api-forms stage | DAM asset |
211
+ | --- | --- | --- |
212
+ | [/test/report-it/](https://staging.wral.com/test/report-it/) | prod (`/forms`): real desk lists and the Studio queue | `39c268dd-06eb-46f9-a6bf-74d04af45bae`, i.e. `pages/report-it.html` as of DEV-1300 |
213
+ | [/test/report-it-dev/](https://staging.wral.com/test/report-it-dev/) | dev (`/dev/forms`): the `ReportIt_Dev` list and the dev content stage | `3c78d978-bcd3-44f9-9906-c417db80de14`, the same page before DEV-1300 (only the `api` attribute and its comment differ) |
214
+
215
+ To change a page:
216
+ 1. Upload the new HTML as a new asset. Use `POST https://api.wral.com/dam/v1/asset/<new uuid>/upload-url` with `dam:write`, then PUT the file with `Content-Type: text/html`.
217
+ 2. `POST https://api.wral.com/publisher/v1/publications` with `publisher:write`, sending `{site, path, content: {}, template: {"$ref": …}, metadata: {httpStatusCode: 200}}`.
218
+ 3. Invalidate the path on CloudFront distribution `E2PUK7RNR73BP4`, because the page is cached for about 6 h.
219
+
220
+ Leave the previous asset in place. Republishing with its `$ref` is the rollback.
221
+
137
222
  ## Notes
138
223
 
139
224
  - `wral-code-input` + helpers are copied from
package/dist/define.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as n from "amazon-cognito-identity-js";
2
- import { W as i, a as r, b as a } from "./wral-code-input-DCemMj53.js";
2
+ import { W as i, a as r, b as a } from "./wral-code-input-BH_1EP8b.js";
3
3
  typeof window < "u" && !window.AmazonCognitoIdentity && (window.AmazonCognitoIdentity = n);
4
4
  const d = {
5
5
  "wral-report-it": a,