@innspel/core 0.4.0 → 0.6.0

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.
@@ -0,0 +1,556 @@
1
+ /**
2
+ * Opak koblingsnøkkel til et maskinsignal hos leietakeren (krasj-ID, sesjons-ID, avspillings-ID). Plattformen validerer at kind er deklarert og at value matcher kind-ens pattern, og tolker eller følger aldri verdien (DD-43).
3
+ */
4
+ type CommonCorrelation = {
5
+ /**
6
+ * Deklarert av leietakeren i innstillingene. «crash» er forhåndsdefinert.
7
+ */
8
+ kind: string;
9
+ value: string;
10
+ };
11
+ /**
12
+ * Maskinlesbar feilkode. Klienten forgrener på denne, aldri på message. Meldingen navngir feltet som feilet, aldri innsendte verdier — den kan inneholde fritekst fra innsenderen.
13
+ */
14
+ type CommonErrorCode = 'validation_failed' | 'unknown_field' | 'text_too_short' | 'text_too_long' | 'correlation_invalid' | 'unauthenticated' | 'feedback_token_required' | 'feedback_token_invalid' | 'feedback_token_expired' | 'mfa_required' | 'insufficient_role' | 'insufficient_scope' | 'screenshots_disabled' | 'submission_not_found' | 'known_issue_not_found' | 'program_not_found' | 'invitation_invalid' | 'task_not_found' | 'follow_up_not_found' | 'participant_not_found' | 'subject_not_found' | 'attachment_not_found' | 'webhook_not_found' | 'delivery_not_found' | 'product_not_found' | 'key_not_found' | 'receipt_not_found' | 'report_not_found' | 'handoff_invalid' | 'invalid_status_transition' | 'reply_exists' | 'invitation_already_answered' | 'program_incomplete' | 'program_full' | 'task_already_completed' | 'follow_up_already_answered' | 'follow_up_not_answerable' | 'report_frozen' | 'webhook_not_verified' | 'attachment_already_uploaded' | 'reply_required' | 'reason_code_required' | 'template_unmodified' | 'fixed_in_required' | 'canonical_is_duplicate' | 'known_issue_conflict' | 'deadline_cannot_be_extended' | 'minors_present_conflict' | 'contacts_exceed_tenant_cap' | 'data_limitations_required' | 'attachment_too_large' | 'attachment_type_not_allowed' | 'rate_limited' | 'not_implemented';
15
+ /**
16
+ * Plattformen innsendingen kom fra. Lukket liste fra dag én, inkludert storskjerm — en verdi som legges til senere er en kontraktendring hos alle SDK-er (ideer/storskjerm-qr-handoff.md).
17
+ */
18
+ type CommonPlatform = 'ios' | 'android' | 'web' | 'tvos' | 'androidtv' | 'tizen' | 'webos';
19
+ /**
20
+ * Kjent feil-kortet slik SDK-et og portalen viser det, FØR innsending i feilsporet (differensiatoren, M2.4). Tre deler: hva, omvei, gjelder versjon (DD-30). Tre svar i klienten: «Ja, jeg også» (KnownIssues.confirm) · «Ligner, men ikke helt» (relatedKnownIssueId på innsendingen) · «Nei, det er noe annet» (vanlig innsending) (DD-29). Aldri Reach — innsenderen ser ikke hvor mange andre.
21
+ */
22
+ type KnownIssuesKnownIssueCard = {
23
+ id: string;
24
+ /**
25
+ * I brukerens ord, 1–3 setninger.
26
+ */
27
+ title: string;
28
+ /**
29
+ * Valgfri omvei, 1–3 setninger.
30
+ */
31
+ workaround?: string;
32
+ status: KnownIssuesKnownIssueStatus;
33
+ /**
34
+ * Versjonen feilen rettes eller er rettet i. Vises som «Rettes i X» når aktiv, «Rettet i X» når fikset.
35
+ */
36
+ fixedIn?: string;
37
+ };
38
+ /**
39
+ * aktiv vises i skjemaet (DD-03); fikset krever fixedIn og utløser Rettet-varselet til alle med Reach (DD-31). Kortet vises for fikset så lenge innsenderens appVersion ≤ fixedIn, og skjules for nyere (DD-30).
40
+ */
41
+ type KnownIssuesKnownIssueStatus = 'aktiv' | 'fikset';
42
+ /**
43
+ * paaminnelse bærer alltid fristen i teksten; tilbud_om_utgang er eneste lovlige form for den betingede kontakten når ingen oppgave er gjort (DD-34).
44
+ */
45
+ type ProgramsFollowUpKind = 'paaminnelse' | 'hvordan_gikk_det' | 'sjekkpunkt' | 'tilbud_om_utgang';
46
+ /**
47
+ * Svar på en oppfølging med spørsmål (kind = hvordan_gikk_det eller sjekkpunkt): tre lukkede valg (fungerte · delvis · ikke) og valgfri fritekst ≤ 140 (domain-model.md Response). Én per FollowUp. Skala 1–5 er FORKASTET 2026-09-07 — se tech-decisions.md M3.2 (forts.).
48
+ */
49
+ type ProgramsFollowUpResponseCreate = {
50
+ outcome: ProgramsTaskOutcome;
51
+ text?: string;
52
+ submissionId?: string;
53
+ };
54
+ /**
55
+ * En oppfølging som er sendt ut til kalleren og ikke besvart. Teksten bærer fristen når kind = paaminnelse (DD-34).
56
+ */
57
+ type ProgramsFollowUpView = {
58
+ id: string;
59
+ programId: string;
60
+ kind: ProgramsFollowUpKind;
61
+ question: string;
62
+ deadlineAt?: string;
63
+ emittedAt: string;
64
+ };
65
+ /**
66
+ * utloept er utledet av klokka, aldri skrevet.
67
+ */
68
+ type ProgramsInvitationStatus = 'sendt' | 'akseptert' | 'avslaatt' | 'utloept';
69
+ /**
70
+ * Invitasjon rettet til kallerens subject. Tokenet finnes ikke her — det kom via leietakerens kanal (DD-12); listen viser at invitasjonen finnes så banneret kan tegnes.
71
+ */
72
+ type ProgramsInvitationView = {
73
+ id: string;
74
+ program: ProgramsProgramView;
75
+ status: ProgramsInvitationStatus;
76
+ expiresAt: string;
77
+ };
78
+ /**
79
+ * Alt om betaprogram for kallerens subject i ett kall — SDK-ets programs.list(). Krever feedback-token; anonym modus har ingen programmer.
80
+ */
81
+ type ProgramsMyPrograms = {
82
+ invitations: Array<ProgramsInvitationView>;
83
+ participations: Array<ProgramsParticipationView>;
84
+ pendingFollowUps: Array<ProgramsFollowUpView>;
85
+ };
86
+ /**
87
+ * trukket: deltakeren gikk ut selv («Gå ut» er alltid synlig, DD-36). Ut av segmentet umiddelbart.
88
+ */
89
+ type ProgramsParticipantStatus = 'aktiv' | 'fullfoert' | 'trukket';
90
+ /**
91
+ * Kallerens egen deltakelse med oppgavestatus. contactsSent / maxContacts vises i fanen.
92
+ */
93
+ type ProgramsParticipationView = {
94
+ id: string;
95
+ program: ProgramsProgramView;
96
+ status: ProgramsParticipantStatus;
97
+ joinedAt: string;
98
+ completions: Array<ProgramsTaskCompletionView>;
99
+ contactsSent: number;
100
+ };
101
+ /**
102
+ * Programmet slik testeren ser det i aksepten (DD-13, DD-32) og i fanen. Ingen andre deltakere, ingen tall om andre.
103
+ */
104
+ type ProgramsProgramView = {
105
+ id: string;
106
+ name: string;
107
+ /**
108
+ * Hva som testes — vises først i aksepten.
109
+ */
110
+ hypothesis: string;
111
+ opensAt: string;
112
+ closesAt: string;
113
+ /**
114
+ * Maks antall kontakter testeren kan få. Vises ved aksept; plattformen nekter å sende flere (DD-14).
115
+ */
116
+ maxContacts: number;
117
+ /**
118
+ * Forpliktelsesfri form: ingen insentiv, ingen frist, ingen vilkår. Tvunget ved minorsPresent (K37).
119
+ */
120
+ commitmentFree: boolean;
121
+ /**
122
+ * Leietakerens vilkår som lenke — aldri avkryssing som binder (DD-37). Alltid null ved commitmentFree.
123
+ */
124
+ termsUrl?: string;
125
+ tasks: Array<ProgramsTask>;
126
+ /**
127
+ * Kjente feil merket visibleToTesters, vist i aksepten (hele lista, DD-13) med samme kort som widgeten.
128
+ */
129
+ knownIssues: Array<KnownIssuesKnownIssueCard>;
130
+ };
131
+ /**
132
+ * Én oppgave i programmet. estimatedMinutes er obligatorisk — aksepten viser «N oppgaver × M minutter» (DD-32).
133
+ */
134
+ type ProgramsTask = {
135
+ id: string;
136
+ /**
137
+ * Rekkefølge fra 1. Oppgave 1 foreslås som «Send ditt første innspill» (DD-33).
138
+ */
139
+ order: number;
140
+ title: string;
141
+ instruction: string;
142
+ /**
143
+ * Skjermen oppgaven gjelder — hint til testeren, aldri en dyplenke plattformen følger.
144
+ */
145
+ screenHint?: string;
146
+ estimatedMinutes: number;
147
+ };
148
+ /**
149
+ * Testeren fullfører en oppgave med utfall (3c «Hvordan gikk det?»). text er den valgfrie setningen «Vil du si én setning om det?» ≤ 140 — vises på programsiden per oppgave, aldri i innboksen, og slettes med pseudonymet. Valgfri kobling til innspillet som ble sendt underveis.
150
+ */
151
+ type ProgramsTaskCompletionCreate = {
152
+ outcome: ProgramsTaskOutcome;
153
+ text?: string;
154
+ submissionId?: string;
155
+ };
156
+ /**
157
+ * Én fullført oppgave, som testeren ser den. text er testerens egen setning fra «Gjort» (3c), aldri fra panelet.
158
+ */
159
+ type ProgramsTaskCompletionView = {
160
+ taskId: string;
161
+ outcome: ProgramsTaskOutcome;
162
+ at: string;
163
+ text?: string;
164
+ submissionId?: string;
165
+ };
166
+ /**
167
+ * Utfallet av én oppgave, valgt av testeren. Tre lukkede valg, aldri skala (rapport 4).
168
+ */
169
+ type ProgramsTaskOutcome = 'fungerte' | 'delvis' | 'ikke';
170
+ /**
171
+ * Tillatte bildetyper. Aldri SVG eller GIF (K9). Sjekkes på magic bytes ved mottak, ikke bare på oppgitt verdi.
172
+ */
173
+ type SubmissionsAttachmentMime = 'image/png' | 'image/jpeg' | 'image/webp';
174
+ /**
175
+ * Vedleggets tilstand etter complete. Verifiseringen (magic bytes, dimensjon, re-enkoding, EXIF-strip) kjører asynkront i isolert prosess; klienten trenger ikke vente.
176
+ */
177
+ type SubmissionsAttachmentView = {
178
+ id: string;
179
+ submissionId: string;
180
+ mime: SubmissionsAttachmentMime;
181
+ bytes: number;
182
+ /**
183
+ * Satt når vedlegget er verifisert og re-enkodet. Utelatt = under behandling.
184
+ */
185
+ processedAt?: string;
186
+ createdAt: string;
187
+ };
188
+ /**
189
+ * Minimal peker til en kjent feil, for visning i innsenderens liste.
190
+ */
191
+ type SubmissionsKnownIssueRef = {
192
+ id: string;
193
+ title: string;
194
+ };
195
+ /**
196
+ * Begrunnelseskode ved avvist. Obligatorisk sammen med fritekst (DD-09). Fire koder, ingen «annet» — en søppelbøtte undergraver tvangen. Rapport 3 navngir kun ikke_prioritert; de tre andre er wireframens forslag og bekreftes av produkteier ved godkjenning av denne kontrakten.
197
+ */
198
+ type SubmissionsReasonCode = 'ikke_prioritert' | 'utenfor_omfang' | 'kan_ikke_gjenskape' | 'allerede_mulig';
199
+ /**
200
+ * Svaret fra leietakeren, slik innsenderen ser det i «mine innspill» (DD-27). Samme tekst som på saken i panelet.
201
+ */
202
+ type SubmissionsReplyView = {
203
+ text: string;
204
+ reasonCode?: SubmissionsReasonCode;
205
+ at: string;
206
+ };
207
+ /**
208
+ * Statuskategori — maskinens felt, utledet av status (DD-22). reviewing: ny, vurderes · active: planlagt, bygges · complete: levert, kjent_feil med fikset KnownIssue · closed: avvist, duplikat.
209
+ */
210
+ type SubmissionsStatusType = 'reviewing' | 'active' | 'complete' | 'closed';
211
+ /**
212
+ * Tilstandsmaskinen i domain-model.md. Navnet innsenderen ser velges per spor i klienten (DD-22): levert vises som «Rettet» i feilsporet og «Levert» i ønskesporet; kjent_feil → fikset vises som «Rettet».
213
+ */
214
+ type SubmissionsSubmissionStatus = 'ny' | 'vurderes' | 'planlagt' | 'bygges' | 'levert' | 'kjent_feil' | 'duplikat' | 'avvist';
215
+ /**
216
+ * Innsenderens egen visning av en innsending. Ingen tekst fra andre, ingen notater, ingen Reach.
217
+ */
218
+ type SubmissionsSubmissionStatusView = {
219
+ id: string;
220
+ type: SubmissionsSubmissionType;
221
+ /**
222
+ * Innsenderens egen tekst, speilet tilbake så «mine innspill» kan vises uten lokal lagring. Tom for kjent_feil-bekreftelser.
223
+ */
224
+ text: string;
225
+ status: SubmissionsSubmissionStatus;
226
+ /**
227
+ * Utledet av status (DD-22). Klienten velger visningsnavn per spor.
228
+ */
229
+ statusType: SubmissionsStatusType;
230
+ /**
231
+ * Svarfristen som dato — det eneste tidsløftet (DD-28). Satt kun i vurderes: statusChangedAt + leietakerens reviewDeadlineDays.
232
+ */
233
+ deadlineAt?: string;
234
+ /**
235
+ * Versjonen feilen er rettet i / ønsket levert i. Satt ved levert, og ved kjent_feil når KnownIssue er fikset (DD-31).
236
+ */
237
+ fixedIn?: string;
238
+ /**
239
+ * Kjent feil denne innsendingen bekreftet («Ja, jeg også») — kortets tittel så «mine innspill» kan vise hva som ble bekreftet.
240
+ */
241
+ knownIssue?: SubmissionsKnownIssueRef;
242
+ /**
243
+ * Kjent feil innsendingen ble lenket til med «Ligner, men ikke helt». Fjernes hvis behandleren avviser lenken.
244
+ */
245
+ relatedKnownIssue?: SubmissionsKnownIssueRef;
246
+ reply?: SubmissionsReplyView;
247
+ /**
248
+ * Om innsendingen har et vedlegg. Selve bildet returneres aldri her — det vises ikke i «mine innspill».
249
+ */
250
+ hasAttachment: boolean;
251
+ createdAt: string;
252
+ statusChangedAt: string;
253
+ };
254
+ /**
255
+ * Sporet. Første valg i widgeten er «Noe virker ikke» / «Jeg ønsker meg noe», aldri et tredje (DD-02).
256
+ */
257
+ type SubmissionsSubmissionType = 'feil' | 'onske';
258
+ /**
259
+ * Hvorfor en innsending feilet — en lukket liste, aldri feilmeldingen (den kan bære tekst).
260
+ */
261
+ type TelemetryFailureReason = 'network' | 'rate_limited' | 'validation' | 'unauthorized' | 'server' | 'unknown';
262
+ /**
263
+ * En bunt hendelser fra én klient. Konteksten er delmengden av SubmissionContext som er et måltall: plattform, appversjon og SDK-versjon (versjonsspredning). Aldri skjerm, aldri locale, aldri OS — de er ikke måltall og ville bare lekket mer.
264
+ */
265
+ type TelemetryTelemetryBatch = {
266
+ events: Array<TelemetryTelemetryEvent>;
267
+ platform: CommonPlatform;
268
+ appVersion?: string;
269
+ sdkVersion: string;
270
+ };
271
+ /**
272
+ * Én hendelse. Feltene utover name og at er hendelsens egne (maaling.md «Hendelser»): type på track_selected og submission_sent, count på known_issue_shown, hasAttachment og offlineQueued på submission_sent, reason på submission_failed, outcome på task_completed. Et felt som ikke hører til hendelsen ignoreres ikke — det gir 400.
273
+ */
274
+ type TelemetryTelemetryEvent = {
275
+ name: TelemetryTelemetryEventName;
276
+ /**
277
+ * Klientens klokke. Serveren klemmer til mottakstiden hvis avviket er over en time.
278
+ */
279
+ at: string;
280
+ type?: SubmissionsSubmissionType;
281
+ /**
282
+ * Antall kjente feil-kort som ble vist (0–3, DD-03).
283
+ */
284
+ count?: number;
285
+ hasAttachment?: boolean;
286
+ offlineQueued?: boolean;
287
+ reason?: TelemetryFailureReason;
288
+ outcome?: ProgramsTaskOutcome;
289
+ };
290
+ /**
291
+ * Hendelsene i maaling.md, ordrett. Lukket liste — et ukjent navn gir 400 validation_failed.
292
+ */
293
+ type TelemetryTelemetryEventName = 'widget_opened' | 'track_selected' | 'known_issue_shown' | 'known_issue_confirmed' | 'submission_sent' | 'submission_failed' | 'invitation_accepted' | 'invitation_declined' | 'task_completed' | 'followup_answered' | 'status_viewed';
294
+
295
+ /**
296
+ * Lagring injiseres av verten — kjernen har ingen nettleser-API-er (CLAUDE.md,
297
+ * «SDK»). Tre metoder er nok: offline-køen er det eneste som lagres, og
298
+ * feedback-tokenet lagres aldri (K20).
299
+ */
300
+ interface InnspelStorage {
301
+ get(key: string): Promise<string | null>;
302
+ set(key: string, value: string): Promise<void>;
303
+ remove(key: string): Promise<void>;
304
+ }
305
+ /**
306
+ * Gir et ferskt feedback-token fra vertens eget token-endepunkt (ES256,
307
+ * `aud=innspel`, `sub` = pseudonym, `exp` ≤ 15 min). Kalles hver gang et token
308
+ * trengs — kjernen cacher det aldri på disk.
309
+ *
310
+ * `null` som RETURVERDI betyr «ingen innlogget bruker akkurat nå»; `null` som
311
+ * OPSJON betyr anonym modus for hele klienten.
312
+ */
313
+ type IdentityProvider = () => Promise<string | null> | string | null;
314
+ /**
315
+ * Den lukkede hvitelista for teknisk kontekst (K5). Leses ved feltnavn — et
316
+ * ukjent felt avvises av `init` og `capture` med feltnavnet i meldingen, før
317
+ * det rekker å bli 400 unknown_field fra plattformen.
318
+ *
319
+ * Aldri enhets-ID, aldri IP, aldri hva som stod på skjermen: `screen` er rutens
320
+ * NAVN. `sdkVersion` settes av kjernen og kan ikke overstyres.
321
+ */
322
+ interface ContextInput {
323
+ platform: CommonPlatform;
324
+ appVersion?: string;
325
+ build?: string;
326
+ os?: string;
327
+ screen?: string;
328
+ locale?: string;
329
+ }
330
+ /** Hendelsene i `docs/maaling.md`. Ingen av dem bærer tekst, skjermbilde eller pseudonym. */
331
+ type TelemetryEvent = {
332
+ name: 'widget_opened';
333
+ } | {
334
+ name: 'track_selected';
335
+ type: 'feil' | 'onske';
336
+ } | {
337
+ name: 'known_issue_shown';
338
+ count: number;
339
+ } | {
340
+ name: 'known_issue_confirmed';
341
+ } | {
342
+ name: 'submission_sent';
343
+ type: 'feil' | 'onske';
344
+ hasAttachment: boolean;
345
+ offlineQueued: boolean;
346
+ } | {
347
+ name: 'submission_failed';
348
+ reason: string;
349
+ } | {
350
+ name: 'invitation_accepted';
351
+ } | {
352
+ name: 'invitation_declined';
353
+ } | {
354
+ name: 'task_completed';
355
+ outcome: string;
356
+ } | {
357
+ name: 'followup_answered';
358
+ } | {
359
+ name: 'status_viewed';
360
+ };
361
+ /**
362
+ * Telemetri går til et injisert grensesnitt. Standard er `noop`; plattformens
363
+ * eget mottak kobles på i M4.2 (tech-decisions.md). Uten opsjonen sendes
364
+ * ingenting noe sted.
365
+ */
366
+ interface Telemetry {
367
+ emit(event: TelemetryEvent): void;
368
+ }
369
+ /** Tekstgrensen per leietaker. Lukket valg — kontrakten har to verdier. */
370
+ type TextMaxLength = 140 | 280;
371
+ interface InnspelOptions {
372
+ /** Plattformens API-rot. Ingen standard: SDK-et skal aldri gjette hvor dataene havner. */
373
+ baseUrl: string;
374
+ /**
375
+ * Den offentlige SDK-nøkkelen (`Product.key`). Skrivende, bundet til
376
+ * bundle-ID eller origin, kan aldri lese (K3). Hører hjemme i appens konfig.
377
+ */
378
+ tenantKey: string;
379
+ /**
380
+ * Funksjon som gir et ferskt feedback-token, eller `null` for anonym modus.
381
+ * Forkastet: stille fallback ved glemt opsjon — anonym modus er et eksplisitt
382
+ * valg (tech-decisions.md, «SDK — dokumentasjon og utvikleropplevelse»).
383
+ */
384
+ identityProvider: IdentityProvider | null;
385
+ /** Offline-køen bor her (DD-41). */
386
+ storage: InnspelStorage;
387
+ /** Teknisk kontekst som følger hver innsending. `platform` er påkrevd. */
388
+ context: ContextInput;
389
+ /**
390
+ * Leietakerens tekstgrense. Ingest-flaten har ingen klientkonfig ennå, så
391
+ * standarden er den strammeste (140, verdien ved `minorsPresent`). Verten
392
+ * overstyrer med verdien fra panelet.
393
+ */
394
+ textMaxLength?: TextMaxLength;
395
+ /** Send-knappen er aktiv fra dette antallet tegn. Standard 10 (DD-44). */
396
+ minTextLength?: number;
397
+ /**
398
+ * Om skjermbilde-steget finnes. Standard `false`: steget skal ikke være en
399
+ * deaktivert knapp, det skal ikke finnes (DD-26). Vedlegg er M1.3.
400
+ */
401
+ screenshotsEnabled?: boolean;
402
+ /** Standard er `noop`. */
403
+ telemetry?: Telemetry;
404
+ /** Injiserbar `fetch`, for test og for verter med egen nettverksstakk. */
405
+ fetch?: typeof fetch;
406
+ /** Tidsavbrudd per kall i millisekunder. Standard 10 000 (wireframe 2i). */
407
+ timeoutMs?: number;
408
+ }
409
+ /**
410
+ * Leietakerens innstillinger slik klienten kjenner dem. Starter som opsjonene fra
411
+ * `init()` (strammest mulig uten dem), og oppdateres av `loadSettings()` fra
412
+ * `GET /v1/ingest/config` (M2.5) — samme objekt, så en holdt referanse følger med.
413
+ */
414
+ interface ResolvedSettings {
415
+ textMaxLength: TextMaxLength;
416
+ minTextLength: number;
417
+ screenshotsEnabled: boolean;
418
+ /** Leietakerens personvernerklæring — «hva samles inn». Finnes først etter `loadSettings()`. */
419
+ privacyUrl?: string;
420
+ }
421
+ /**
422
+ * Bildet slik verten gir det fra seg — Blob (React Native og nettleser),
423
+ * ArrayBuffer eller en typed array. Kjernen leser bare lengden; innholdet går
424
+ * rett til lagringen.
425
+ */
426
+ type AttachmentBody = Blob | ArrayBuffer | ArrayBufferView<ArrayBuffer>;
427
+ /**
428
+ * Ett skjermbilde, MASKERT på klienten før dette (K4, DD-39, DD-40). Kjernen
429
+ * sjekker grensene (PNG/JPEG/WebP, ≤ 5 MB, ≤ 4096², K9) og kaster med feltnavn
430
+ * før noe går på nettet; plattformen sjekker dem igjen før dekoding.
431
+ */
432
+ interface AttachmentInput {
433
+ mime: SubmissionsAttachmentMime;
434
+ body: AttachmentBody;
435
+ width: number;
436
+ height: number;
437
+ }
438
+ /**
439
+ * Hva som skjedde med vedlegget etter at teksten var lagret (DD-42).
440
+ * `failed` er ikke en feil for innsendingen — saken står, uten bilde — men
441
+ * UI-et skal si det: «Sendt — skjermbildet kunne ikke legges ved».
442
+ */
443
+ type AttachmentOutcome = {
444
+ status: 'uploaded';
445
+ attachment: SubmissionsAttachmentView;
446
+ } | {
447
+ status: 'failed';
448
+ error: Error;
449
+ }
450
+ /** Teksten ble køet offline; et skjermbilde køes aldri (DD-41), så det ble forkastet. */
451
+ | {
452
+ status: 'dropped';
453
+ };
454
+ /** Felles felter for begge spor. */
455
+ interface CaptureBase {
456
+ text: string;
457
+ /**
458
+ * Skjermbilde, maskert på klienten. Sendes ETTER teksten, i egen forespørsel,
459
+ * og kan feile alene (DD-42) — se `CaptureResult.attachment`.
460
+ */
461
+ attachment?: AttachmentInput;
462
+ /**
463
+ * Legges på konteksten fra `init` — typisk `screen`. Et felt satt til
464
+ * `undefined` FJERNES fra innsendingen (DD-05, «Fjern» i kontekstlinja); et
465
+ * felt som ikke nevnes, beholdes fra `init`.
466
+ */
467
+ context?: Partial<ContextInput>;
468
+ /**
469
+ * Idempotensnøkkel for offline-køen. Settes av kjernen hvis den utelates:
470
+ * en ny UUID per INNSENDING, aldri per enhet eller installasjon (K20).
471
+ */
472
+ clientRef?: string;
473
+ /** Krever feedback-token og aktiv deltakelse. Betaprogram er M3. */
474
+ programId?: string;
475
+ taskId?: string;
476
+ }
477
+ /** «Noe virker ikke» — eneste spor med koblingsnøkler og lenke til kjent feil (DD-02). */
478
+ interface CaptureFeil extends CaptureBase {
479
+ type: 'feil';
480
+ /** Opake koblingsnøkler til maskinsignaler hos leietakeren, maks tre. `crash` er forhåndsdefinert (DD-43). */
481
+ correlation?: CommonCorrelation[];
482
+ /** «Ligner, men ikke helt» (DD-29): lenke uten tvunget match. */
483
+ relatedKnownIssueId?: string;
484
+ }
485
+ /** «Jeg ønsker meg noe» — ingen koblingsnøkler, ingen reproduksjonsfelt (DD-02). */
486
+ interface CaptureOnske extends CaptureBase {
487
+ type: 'onske';
488
+ }
489
+ type CaptureInput = CaptureFeil | CaptureOnske;
490
+ type CaptureResult = {
491
+ status: 'sent';
492
+ submission: SubmissionsSubmissionStatusView;
493
+ attachment?: AttachmentOutcome;
494
+ } | {
495
+ status: 'queued';
496
+ clientRef: string;
497
+ attachment?: {
498
+ status: 'dropped';
499
+ };
500
+ };
501
+ /** En rad i offline-køen. Kun tekst — et skjermbilde køes aldri (rapport 3, kap. 5). */
502
+ interface QueuedSubmission {
503
+ clientRef: string;
504
+ type: 'feil' | 'onske';
505
+ text: string;
506
+ queuedAt: string;
507
+ }
508
+ /** Resultatet av en flush. */
509
+ interface FlushResult {
510
+ sent: number;
511
+ /** Rader plattformen avviste med 400 — de blir aldri gyldige og forkastes. */
512
+ failed: number;
513
+ /** Rader som fortsatt venter, typisk fordi nettet er nede. */
514
+ remaining: number;
515
+ }
516
+ /**
517
+ * En rad i «Mine innspill» (DD-27, DD-41): plattformens egne innsendinger, pluss
518
+ * køen gjort synlig. `pending` skiller dem — en køet rad har ingen saksnummer.
519
+ */
520
+ type MySubmission = (SubmissionsSubmissionStatusView & {
521
+ pending?: false;
522
+ }) | {
523
+ pending: true;
524
+ clientRef: string;
525
+ type: 'feil' | 'onske';
526
+ text: string;
527
+ queuedAt: string;
528
+ };
529
+ /** Klassene mønstervarselet kjenner (DD-46). */
530
+ type PatternKind = 'email' | 'phone' | 'card' | 'ip' | 'token';
531
+ interface PatternFinding {
532
+ kind: PatternKind;
533
+ match: string;
534
+ start: number;
535
+ end: number;
536
+ }
537
+ interface KnownIssueQuery {
538
+ screen?: string;
539
+ version?: string;
540
+ platform?: CommonPlatform;
541
+ }
542
+ /**
543
+ * Visningen `openFeedback` åpner. Registreres av `@innspel/react-native`;
544
+ * kjernen har ingen UI (CLAUDE.md, «SDK»).
545
+ */
546
+ interface Presenter {
547
+ open(options?: OpenFeedbackOptions): Promise<void>;
548
+ }
549
+ interface OpenFeedbackOptions {
550
+ /** Rutenavnet innsenderen kom fra. Styrer hvilke kjente feil som vises (DD-30). */
551
+ screen?: string;
552
+ /** Start i et bestemt spor og hopp over 2b. */
553
+ track?: 'feil' | 'onske';
554
+ }
555
+
556
+ export type { AttachmentInput as A, ProgramsTask as B, ContextInput as C, ProgramsProgramView as D, SubmissionsReasonCode as E, FlushResult as F, SubmissionsReplyView as G, SubmissionsStatusType as H, InnspelOptions as I, SubmissionsSubmissionStatus as J, KnownIssueQuery as K, SubmissionsSubmissionType as L, MySubmission as M, ProgramsTaskOutcome as N, OpenFeedbackOptions as O, ProgramsMyPrograms as P, QueuedSubmission as Q, ResolvedSettings as R, SubmissionsSubmissionStatusView as S, TelemetryEvent as T, Telemetry as U, TextMaxLength as V, TelemetryTelemetryBatch as W, CaptureInput as a, CaptureResult as b, KnownIssuesKnownIssueCard as c, ProgramsParticipationView as d, ProgramsTaskCompletionCreate as e, ProgramsTaskCompletionView as f, ProgramsFollowUpResponseCreate as g, SubmissionsAttachmentView as h, PatternFinding as i, Presenter as j, CommonErrorCode as k, SubmissionsAttachmentMime as l, AttachmentBody as m, AttachmentOutcome as n, CaptureFeil as o, CaptureOnske as p, CommonCorrelation as q, ProgramsFollowUpKind as r, ProgramsFollowUpView as s, IdentityProvider as t, InnspelStorage as u, ProgramsInvitationView as v, SubmissionsKnownIssueRef as w, KnownIssuesKnownIssueStatus as x, PatternKind as y, CommonPlatform as z };