General source code refactoring
This commit is contained in:
198
docs/architecture.md
Normal file
198
docs/architecture.md
Normal file
@@ -0,0 +1,198 @@
|
||||
# Architecture and Compatibility Contracts
|
||||
|
||||
This document describes the integrated modular implementation. Verification and
|
||||
preexisting risks are tracked in [refactoring.md](refactoring.md).
|
||||
|
||||
## Sources, Outputs, and Runtime Boundaries
|
||||
|
||||
- Editable sources are factory modules under `src/`; the former monoliths were removed.
|
||||
- `scripts/sources.cjs` explicitly lists modules for each context. `compose.cjs`
|
||||
validates syntax, serializes CSS, wraps the modules in an IIFE and calls the
|
||||
corresponding application factory/start method. `build.mjs` writes two packages.
|
||||
- `dist/chromium` serves Chrome and Edge; `dist/firefox` serves Firefox. Do not edit outputs.
|
||||
- Both manifests use V3. Chromium has a classic background service worker; Firefox
|
||||
uses `background.scripts`. Neither entry point is declared as a module.
|
||||
- Content scripts run at `document_idle`, in all matching frames on the two
|
||||
configured Fusion welcome pages. Their code also checks the hostname/path.
|
||||
- There are no extension UI pages, injected page-context scripts, custom CSP,
|
||||
declared execution world, or web-accessible resources.
|
||||
- Permissions remain `cookies` and `storage`, with host access limited to the
|
||||
configured Fusion host and `spa.oracle.com`.
|
||||
|
||||
Content owns the DOM and per-frame state. Background owns privileged cookies,
|
||||
temporary tabs, extension storage and SPA requests. These contexts communicate
|
||||
using serializable runtime messages, not shared variables. Page localStorage is
|
||||
different from extension storage and is not a safe place for credentials.
|
||||
|
||||
## Current Ownership and Side Effects
|
||||
|
||||
| Context | Responsibilities | State and effects |
|
||||
| --- | --- | --- |
|
||||
| Content | Fusion tile and main/preferences/consumption modals | DOM nodes, injected CSS, keyboard/pointer/resize listeners, MutationObserver |
|
||||
| Content | Opportunity query and presentation | Filter sets, sorting, search, request versions, column formatters, dashboard animation |
|
||||
| Content | Products UI | Current request ID, product map, expanded rows, progress, last update |
|
||||
| Content | Consumption UI | Plan state, per-plan/period trend cache, chart navigation and selected series |
|
||||
| Content | AI summary | Per-opportunity in-flight state and summary; fresh generation on expansion |
|
||||
| Content | Authentication/debug | General and scoped token promises, SPA authorizations, request logs, visibility flag |
|
||||
| Background | Message dispatcher | Synchronously registered listener, asynchronous replies using `return true` |
|
||||
| Background | Products | Four workers, per-opportunity in-flight map, lazy cache read and serialized writes |
|
||||
| Background | Cookie/session recovery | Inactive tabs, polling/retry delays, cleanup in `finally` |
|
||||
| Background | SPA operations | HTTP/JSON parsing, account/plan extraction and debug envelopes |
|
||||
|
||||
Closing the main modal hides it rather than destroying it. Many requests can
|
||||
continue while it is hidden. Version and request-ID checks suppress stale UI
|
||||
updates; they do not abort network traffic. No AbortController is currently used.
|
||||
Some listeners have window guards; there is no general disposal lifecycle.
|
||||
|
||||
## Authentication and API Routing
|
||||
|
||||
Never substitute one token family for another or assume an opaque token is a JWT.
|
||||
Production tokens are held in memory, not deliberately persisted by the extension.
|
||||
|
||||
| Credential | Acquisition | Consumers | Lifetime/recovery |
|
||||
| --- | --- | --- | --- |
|
||||
| XSRF | Background cookie lookup, then content `document.cookie` fallback | `x-xsrf-token` for both tokenrelays | Cookie recovery tab on missing/invalid response; existing retry rules |
|
||||
| Fusion general | GET `/fscmRestApi/tokenrelay` | Opportunity POST and product GET Bearer | Content promise/cache; no expiry-based refresh equivalent to Sales Common |
|
||||
| Sales Common | GET `/fscmRestApi/tokenrelay?scopesfq=urn%3Aopc%3Aresource%3Afusion%3Aeeho%3Asales-common%2F` | AI summary Bearer | In-memory `expires_in`, shared in-flight acquisition; at most one summary retry after 401/403 |
|
||||
| ACCP-TS | SPA consumer service `uiaasHeader.value` | Account summary authorization | Retrieved with the consumer service response; expiry recorded, not automatically acted on |
|
||||
| OCICONS-TS | SPA consumer service `uiaasHeader.value` | Account plans and consumption trend authorization | Same service response, distinct credential from ACCP-TS |
|
||||
|
||||
Fusion calls use `https://eeho.fa.us2.oraclecloud.com`; SPA calls use
|
||||
`https://spa.oracle.com/oalcrm/web/api/`. Preserve `credentials: include` and
|
||||
operation-specific headers rather than unifying all calls under a default token.
|
||||
|
||||
| Request | Method/path | Important contract |
|
||||
| --- | --- | --- |
|
||||
| requestOpportunities | POST `/crmRestApi/searchResources/11.13.18.05/custom-actions/queries` | RecordSet OR plus EffectiveDate AND, original fields, Preference transient, pages of 15 |
|
||||
| requestOpptyProducts | GET `/crmRestApi/rest/rv:be91c002-2e5d-4ed2-a37e-e0c837bf141f/en/11.13.18.05:9/opportunities/{number}/child/ChildRevenue` | Encoded identifier, original query/fields/order, count/offset pagination, maximum 250 pages |
|
||||
| requestGenerateAiSummary | POST `/api/sales-common/gen-ai/v1/summarizations/generate` | `{path,promptCode,object,puid}`; prompt `cx.sales.generate_opportunity_summary`; only summaryText displayed |
|
||||
| requestConsumerTokenService | GET `g2m-consumer-application/consumerTokenService` | No-store; parse JSON; HTML 200 recovery via inactive SPA UI tab; maximum five HTTP attempts |
|
||||
| requestAccountSummary | POST `provider-proxy/g2m-account/service/accountsummary` | ACCP-TS; `[{key:"regId",value:partyNumber}]` |
|
||||
| requestAccountPlans | POST `provider-proxy/g2m-consumption/service/v1/account/accountPlans/{id}` | OCICONS-TS; original hierarchy/products/language/planStatus payload |
|
||||
| requestConsumptionService{Period} | GET `provider-proxy/g2m-consumption/service/v1/plan/trend/{subPlanNum}?quarter=All&timePeriod={period}` | G2m-Authorization; quarterly/monthly/weekly/daily; weekly default |
|
||||
|
||||
SPA parsing removes BOM and the existing anti-JSON-hijacking prefixes before
|
||||
JSON.parse. Content uses response.json directly. Do not silently unify these behaviors.
|
||||
POST retry policies require operation-specific review; do not add generic retries.
|
||||
|
||||
## Message Contracts
|
||||
|
||||
All names below have the `opportunitiesExtension.` prefix. Unknown messages return
|
||||
false without a response. Supported background messages return true immediately
|
||||
and later call sendResponse. `platform/background-api.js` centralizes the existing
|
||||
callback/promise differences. `platform/content-messages.js` retains the original
|
||||
cookie callback path as well as general runtime messaging; no browser behavior
|
||||
was silently changed during extraction.
|
||||
|
||||
| Message | Input | Result |
|
||||
| --- | --- | --- |
|
||||
| getXsrfToken | type | ok, cookieName, token, matchedCookieNames, lookupDetails; error on failure |
|
||||
| refreshXsrfCookie | type; sender tab context | ok, refreshed, cookieName, durationMs, error |
|
||||
| requestOpptyProducts | requestId, accessToken, optyNumbers, cacheMaxAgeMs | ok, requestId, completed, total, failed, cacheHits; error envelope on dispatcher failure |
|
||||
| opptyProductsProgress | Background to sender tab/frame | requestId, state, counters; per-item optyNumber/items/fromCache/cachedAt or error |
|
||||
| requestConsumerTokenService | type; sender tab context | ok, authorizations.accountSummary/accountPlans, debugRequests |
|
||||
| requestAccountPlans | partyNumber, authorizations | ok, accountPlanId, plans, debugRequests |
|
||||
| requestConsumptionTrend | subPlanNum, period, authorization | ok, subPlanNum, period, items, debugRequests |
|
||||
|
||||
SPA failures return `{ok:false,error,debugRequests}`. Progress states include
|
||||
`running`, `complete` and `complete-with-errors`; content additionally tracks idle
|
||||
and error states. A new content request ID rejects progress from an older job.
|
||||
Do not expose a caller-provided arbitrary request URL through the background.
|
||||
|
||||
## Storage Contracts
|
||||
|
||||
| Location/key | Value |
|
||||
| --- | --- |
|
||||
| Page localStorage: `opportunities-extension-filter-preferences` | JSON object: period, stages, statuses, customerKeys, ownerKeys, customerSearch, ownerSearch, tableSearch; unset customer/owner selections may be null |
|
||||
| Page localStorage: `opportunities-extension-theme` | `light` or `dark` |
|
||||
| Page localStorage: `opportunities-extension-opportunity-type-preferences` | JSON object: opportunityTypeValues, opptyProductsCacheHours |
|
||||
| Extension storage.local: `opportunitiesExtension.opptyProductsCache.v1` | Object indexed by OptyNumber, each entry `{fetchedAt,items}` |
|
||||
|
||||
Product TTL defaults to 24 hours and is capped at 30 days in background. Storage
|
||||
failures are tolerated for the active view. Recreating background reloads stored
|
||||
products but does not restore in-flight jobs. Cache TTL does not physically delete
|
||||
expired entries. Account/container isolation limitations are tracked separately.
|
||||
|
||||
## UI Contracts
|
||||
|
||||
Preserve labels/IDs/classes, column order, URLs, clipboard behavior, sort/filter
|
||||
semantics, formatting, theme colors, keyboard shortcuts and row expansion.
|
||||
WON includes WON_PENDING without rewriting StatusCode. Owner uses first/last name
|
||||
with the existing fallbacks. Changing reference resets customers/owners to all;
|
||||
closing/reopening preserves search. Fiscal years begin in June; RENEWALS currently
|
||||
has no date range and therefore does not load opportunities.
|
||||
|
||||
Preserve SVG chart data normalization, animation, tooltips and series selection.
|
||||
AI text is inserted with textContent. Debug masking and DOM isolation have known
|
||||
limitations; see the separate security backlog rather than assuming full redaction.
|
||||
|
||||
## Module Ownership and Dependencies
|
||||
|
||||
`content/main.js` and `background/main.js` only initialize. Each `application.js`
|
||||
is a composition root: constructs feature-owned state and factories, wires explicit
|
||||
function dependencies, then exposes `start`. The returned components are available
|
||||
to isolated tests, not published on the page/global object in production.
|
||||
|
||||
Factories do not import or instantiate peers. Features receive service/auth ports;
|
||||
services/auth receive transport/platform ports; pure models receive data. The
|
||||
composition roots supply callback notifications for UI updates and debug events,
|
||||
preserving existing interactions without module-import cycles. Shared messages
|
||||
are the only source included in both contexts, with distinct instances/state.
|
||||
Some stateful UI collaborators intentionally share a feature-owned state object;
|
||||
these objects are created per application, never stored in a global registry.
|
||||
|
||||
| Original responsibility | Integrated module(s) | Reason for boundary |
|
||||
| --- | --- | --- |
|
||||
| content initialization/tile | `content/main.js`, `fusion-page.js` | Page lifecycle and route guard |
|
||||
| modal/theme/CSS | `content/modal.js`, `theme.js`, `styles.js`, `styles/redwood.css` | DOM shell separate from operations and cascade |
|
||||
| fiscal dates/query payload | `features/opportunities/fiscal-periods.js`, `services/fusion/opportunities.js` | Pure date rules vs HTTP operation |
|
||||
| table/search/filters/formatting/dashboard | `features/opportunities/` | Related presentation responsibilities, explicit state |
|
||||
| saved settings | `features/preferences/storage.js`, `view.js` | Serialization/fallbacks vs dialog |
|
||||
| token families | `auth/content-session.js`, `sales-common.js`, `token-relay.js`, `spa-credentials.js` | Different credentials and lifetime policies |
|
||||
| cookie lookup/recovery, SPA session | `auth/xsrf-*.js`, `consumer-session.js` | Privileged recovery separate from UI |
|
||||
| product queue/cache | `features/products/background-jobs.js`, `cache.js`, `services/fusion/products.js` | Scheduling, persistence and pagination |
|
||||
| product progress/details | `features/products/content-jobs.js`, `details.js` | Message consumer vs row rendering |
|
||||
| AI summary | `features/ai-summary/content.js`, `state.js` | Per-opportunity lifecycle, safe text and auth port |
|
||||
| consumption | `features/consumption/`, `services/spa/` | Plans, chart model/view/controller vs HTTP operations |
|
||||
| debug | `features/debug/content-log.js`, `content-view.js` | Retention/formatting vs DOM presentation |
|
||||
| background dispatcher | `background/messages.js`, `shared/messages.js` | Stable serializable message contracts |
|
||||
| browser APIs | `platform/background-api.js`, `content-messages.js` | Only APIs actually used, not a universal wrapper |
|
||||
|
||||
The background composition deliberately has no DOM dependency. Listener registration
|
||||
is synchronous, before any storage read or request. Worker restart reconstructs
|
||||
volatile state and lazily reads the existing product cache; tokens are not persisted.
|
||||
Content effects (DOM, fetch, storage, animation) enter through the environment at
|
||||
the composition root. localStorage access stays lazy to retain blocked-storage
|
||||
fallbacks. Tests may inject effects or individual callback ports without changing
|
||||
source strings. Time-sensitive modules are tested with isolated clocks.
|
||||
|
||||
## Adding a Feature
|
||||
|
||||
1. Define its message/API/storage contract and synthetic expected behavior first.
|
||||
2. Add a factory under the owning feature, or a service under the correct host.
|
||||
Accept narrow function dependencies; do not call another factory inside it.
|
||||
3. Add its source path to the appropriate array in `scripts/sources.cjs`. Source
|
||||
inclusion and duplicate factory checks run automatically.
|
||||
4. Construct it in that context's `application.js`, supplying auth, platform and
|
||||
render callbacks explicitly. Extend `background/messages.js` only if crossing
|
||||
contexts is necessary; do not expose arbitrary destinations.
|
||||
5. Add a `tests/*.test.cjs` suite using `tests/support/application.cjs` for composed
|
||||
integration or `vm.Script` for an individual pure factory. Use only synthetic
|
||||
data and fail unexpected network requests.
|
||||
6. Run tests, build and `--check`; inspect the local fixture and load both packages
|
||||
in the target browsers. Record any browser not available for verification.
|
||||
|
||||
As a concrete example, adding a new consumption period should first define its
|
||||
request/data/authorization contract and synthetic tests, then extend the period
|
||||
allowlist and normalization/presentation through the existing trend message. It
|
||||
must not add a URL-proxy message or reuse the general Fusion token. These edits
|
||||
belong in the consumption feature and SPA service, not the bootstrap.
|
||||
|
||||
## Source vs Generated Code
|
||||
|
||||
Distribution `content.js` and `background.js` are generated bundles and may remain
|
||||
large. No copy/export/execute JavaScript generator feature was found in the source.
|
||||
AI summaries are text, not executable JavaScript. No empty generators subsystem
|
||||
was added. Build serialization uses JSON.stringify for CSS, retains quotes,
|
||||
backslashes, Unicode and line breaks, and is syntax-checked by vm.Script. Visual
|
||||
fixtures now load composed scripts normally; they no longer eval rewritten sources.
|
||||
63
docs/browser-smoke.md
Normal file
63
docs/browser-smoke.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Native Browser Validation
|
||||
|
||||
This checklist complements the synthetic tests; it is not evidence of a native
|
||||
pass until executed and recorded separately for each browser.
|
||||
|
||||
## Preconditions
|
||||
|
||||
- Use an authorized test profile/account. Do not delete cookies, sign out, change
|
||||
account security settings or inspect credential values to force failure cases.
|
||||
- Connect Chrome/Edge through Settings > Computer use for assisted browser tests.
|
||||
Firefox needs a separate supported/manual test session.
|
||||
- Run `node scripts/build.mjs --check` and `node scripts/test.cjs` first.
|
||||
- Load `dist/chromium` using Load unpacked in Chrome/Edge, or load
|
||||
`dist/firefox/manifest.json` as a temporary Firefox add-on. Verify the source
|
||||
directory and version 1.0.1; avoid testing a previously installed stale copy.
|
||||
- Keep debug secrets hidden. Record only status codes, request names, durations
|
||||
and sanitized errors. Do not export real tokens, response bodies or account data.
|
||||
- AI generation and tests requiring a deliberately expired session must use an
|
||||
explicitly authorized test environment. Do not trigger live writes solely to
|
||||
complete this checklist.
|
||||
|
||||
## Checklist
|
||||
|
||||
| Check | Expected result |
|
||||
| --- | --- |
|
||||
| Package load | No manifest/background/content syntax errors; no additional permissions |
|
||||
| Both Fusion welcome routes | Exactly one tile before the add-icon item; no tile on unrelated pages |
|
||||
| Modal open/close/reopen | Same search value and matching results; Esc closes the correct dialog |
|
||||
| Filters and sorting | Correct customer/owner/stage/status/text combinations; WON includes WON_PENDING |
|
||||
| Reference change | Customer and owner reset to all; stale responses do not overwrite new results |
|
||||
| Preferences | Save/reopen retains selected record sets and cache duration; restore original settings afterward |
|
||||
| Products | Progress completes; badges/counts and expanded rows agree; warm cache avoids redundant product fetches |
|
||||
| AI in authorized test environment | Summary appears without replacing products; concurrent expansions share scoped-token acquisition; reopen uses valid token |
|
||||
| Consumption | Dialog opens promptly, weekly chart by default; plan/period changes and series filters work |
|
||||
| Themes and layout | Light/dark controls work; check long names, WON_PENDING and full update timestamps |
|
||||
| Debug | Expected operation names/statuses; sensitive values remain hidden |
|
||||
| Background restart | Close its inspector, allow suspension, then trigger a message; listener responds and stored product cache is reloaded |
|
||||
| Multiple tabs | Progress remains scoped to requesting frame/job; no duplicate UI/listeners from normal navigation |
|
||||
| Firefox containers | Test only in authorized containers; record current cookie/cache isolation limitations without silently changing behavior |
|
||||
| Natural session expiry | When encountered, record recovery outcome and temporary-tab cleanup without revealing cookies or forcing sign-out |
|
||||
|
||||
Background interruption does not currently resume in-flight jobs. Do not mistake
|
||||
that known limitation for a new regression or claim a mocked restart proves native
|
||||
worker suspension. Any differences must be compared with the pre-refactor behavior.
|
||||
|
||||
## Execution Record
|
||||
|
||||
2026-09-17 preflight:
|
||||
|
||||
| Target | Discovery | Native test result |
|
||||
| --- | --- | --- |
|
||||
| Chrome | Executable version 153.0.8010.37; automation not connected | Blocked pending connection |
|
||||
| Edge | Executable version 153.0.4234.32; automation not connected | Blocked pending connection |
|
||||
| Firefox | No executable found at the checked standard Program Files path; installation not confirmed | Not run |
|
||||
|
||||
The running-process diagnostic was denied by the environment, so browser running
|
||||
state was not established. Connected targets were Brave and the in-app browser;
|
||||
neither was substituted for this native matrix. The user chose to connect
|
||||
Chrome/Edge. All five local suites and the output consistency check passed again.
|
||||
No real Fusion/SPA calls, runtime changes, release or commit were made in preflight.
|
||||
|
||||
For each completed run, append date, browser/version, package path, checklist
|
||||
outcomes, sanitized errors and remaining gaps. Never mark unexecuted checks passed.
|
||||
184
docs/refactoring.md
Normal file
184
docs/refactoring.md
Normal file
@@ -0,0 +1,184 @@
|
||||
# Incremental Refactoring Record
|
||||
|
||||
## Stage 1: Characterization Baseline
|
||||
|
||||
Stage 1 initially added tests and documentation only, before any runtime extraction.
|
||||
The following records that historical baseline. The completed integration and
|
||||
remaining verification gaps are recorded under "Completed Extraction Stages" below.
|
||||
|
||||
### Coverage Added
|
||||
|
||||
`tests/characterization.test.cjs` contains 22 test cases using Node's built-in
|
||||
test runner, assert and vm. `tests/support/characterization.cjs` provides isolated
|
||||
fixtures: no real browser cookies, account identifiers, tokens or network access.
|
||||
Unexpected fetches reject rather than falling through to global fetch.
|
||||
|
||||
- Exact current manifests and source/output equality, with classic-script syntax validation.
|
||||
- Disallowed-origin initialization and reinjection when the tile already exists.
|
||||
- Fiscal boundaries, leap years, rolling quarters and unsupported RENEWALS.
|
||||
- Full opportunity query payload, pagination offsets/counts and stale request versions.
|
||||
- Filter storage round-trip, WON_PENDING, search, numeric sort, reference reset and malformed preferences.
|
||||
- Missing-cookie tokenrelay recovery and existing 400/401/403 retry limit.
|
||||
- Chrome callback and Firefox promise mocks for background dispatch, storage, cookies and tabs.
|
||||
- Product pagination, default/custom TTL, concurrency limit, in-flight sharing and partial errors.
|
||||
- Persisted product reads after recreating the background context; storage failures and stalled pages.
|
||||
- XSRF discovery, recovery timeout, successful recovery and temporary-tab cleanup.
|
||||
- SPA credential selection, account payloads, encoded identifiers and debug envelopes.
|
||||
- Invalid messages, network errors, HTTP 401 and HTTP 200 invalid JSON in consumption.
|
||||
|
||||
Existing suites remain intact: consumption normalization/requests, consumer-session
|
||||
recovery, AI summary rendering/state, scoped token reuse/expiry and bounded retry.
|
||||
Tests for the current security defects are deliberately not encoded as acceptable
|
||||
behavior. They belong to separately approved fixes.
|
||||
|
||||
### Former Temporary Test Seam
|
||||
|
||||
The original content IIFE had no exports, so baseline tests initially exposed
|
||||
functions before initialization with a guarded source marker. That temporary
|
||||
mechanism is now removed. Tests use the actual application factories through
|
||||
`tests/support/application.cjs`, without replacing source strings. Background
|
||||
integration tests still execute the production listener and asynchronous replies.
|
||||
|
||||
### Running Checks
|
||||
|
||||
```sh
|
||||
npm test
|
||||
npm run check
|
||||
```
|
||||
|
||||
Without npm, use the Node commands in package.json individually. The new suite is:
|
||||
|
||||
```sh
|
||||
node tests/characterization.test.cjs
|
||||
```
|
||||
|
||||
At baseline, `build.mjs --check` did not compare output contents. It now checks
|
||||
both generated manifests and both scripts byte-for-byte against composition.
|
||||
Characterization tests retain the exact manifest expectations.
|
||||
|
||||
Stage-1 verification on Node.js v24.19.0:
|
||||
|
||||
| Command | Result |
|
||||
| --- | --- |
|
||||
| `node --check src/content.js` and `node --check src/background.js` | Passed |
|
||||
| `node --check tests/support/characterization.cjs` | Passed |
|
||||
| `node tests/consumptionTrend.test.cjs` | Passed |
|
||||
| `node tests/consumerTokenSessionRetry.test.cjs` | Passed |
|
||||
| `node tests/aiSummary.test.cjs` | Passed |
|
||||
| `node tests/characterization.test.cjs` | 22 passed, 0 failed |
|
||||
| `node scripts/build.mjs --check` | Passed; distribution equivalence also checked by the suite |
|
||||
| `git diff --check` | Passed |
|
||||
|
||||
The individual commands from the npm scripts were executed directly. No build
|
||||
regeneration was needed because runtime sources and the build were unchanged;
|
||||
`git diff -- src dist scripts/build.mjs` was empty.
|
||||
|
||||
### Verification Limits
|
||||
|
||||
- API mocks are not proof of Chrome/Edge/Firefox compatibility or real authentication.
|
||||
- Recreating a VM tests cache rehydration, not actual service-worker suspension or job recovery.
|
||||
- DOM mocks do not prove layout, focus, accessibility or SPA lifecycle correctness.
|
||||
- The original visual fixture used eval. The completed extraction removed it and
|
||||
serves the composed factory through a normal local script instead.
|
||||
- No installed-browser smoke test or live Fusion request was performed in stage 1.
|
||||
- No JavaScript export/generator feature was located. Do not create a generators
|
||||
directory until its actual source and standalone-output contracts are identified.
|
||||
|
||||
## Separate Security and Reliability Backlog
|
||||
|
||||
These are preexisting observations, not authorized functional changes in this refactor.
|
||||
|
||||
| Issue | Evidence/impact | Separate change to evaluate |
|
||||
| --- | --- | --- |
|
||||
| Debug redaction after truncation | Invalid/truncated JSON is returned unmasked by formatDebugBody; reproduced with a synthetic token | Redact before truncation, fail closed on malformed bodies, test all response shapes |
|
||||
| Debug secrets and shared DOM | Raw headers/bodies are retained for the reveal control; revealed text is in page DOM | Review retention, safe diagnostic schema and whether revealing credentials remains acceptable |
|
||||
| Cookie store selection | Lookup scans all stores instead of binding to sender account/container | Scope selection to the requesting context and test multi-account behavior |
|
||||
| Product cache isolation | Cache and in-flight keys use OptyNumber only | Design identity partitioning and explicit cache migration/retention policy |
|
||||
| Privileged message validation | No explicit sender identity/origin check; supplied header names are accepted | Validate senders/messages and allowlist headers without introducing an arbitrary proxy |
|
||||
| Session tab retry | Opening failures retry indefinitely; interruption can strand work | Decide cancellation/limits and worker lifecycle recovery explicitly |
|
||||
| DOM lifecycle | Observer can remain active; guards do not cover every reinjection/resize path | Define ownership/disposal and characterize navigation before changing behavior |
|
||||
| Token expiry | General/SPA tokens have policies different from Sales Common | Review independently; do not unify policies as part of extraction |
|
||||
|
||||
Never include real secrets in repro cases, snapshots, documentation or test output.
|
||||
Do not add persistent token storage to compensate for worker termination.
|
||||
|
||||
## Completed Extraction Stages
|
||||
|
||||
All modules listed below are integrated through `scripts/sources.cjs` and the
|
||||
two composition roots. Former `src/content.js` and `src/background.js` were removed;
|
||||
their names remain only for the generated distribution scripts. No version change,
|
||||
commit, publication, runtime dependency, permission expansion or CSP change occurred.
|
||||
|
||||
| Stage/responsibility | Files/boundaries | Preserved contracts and evidence | Remaining risk/next safe step |
|
||||
| --- | --- | --- | --- |
|
||||
| Build and pure logic | `scripts/compose.cjs`, `sources.cjs`; fiscal-periods, formatters, consumption model | Classic IIFEs, exact manifests, dates, payload/normalization tests; syntax checked per source and composed bundle | Native browser package loading still needs a smoke test |
|
||||
| Platform and dispatch | `platform/`, `background/main.js`, `messages.js`, `shared/messages.js` | Sync listener registration, callback/promise mocks, async responses, sender-frame progress and unknown-message behavior | Sender validation is a separate security change |
|
||||
| Auth and HTTP operations | `auth/`, `services/` | Credential selection, scoped-token reuse/expiry, 401/403 retry, missing-cookie and HTML-session recovery, request/debug envelopes | Real SSO and worker suspension not simulated completely |
|
||||
| Products | `features/products/` | Four-worker queue, pagination, TTL, cache restore, in-flight sharing, partial errors and expansion behavior | Existing identity/cache-retention policy unchanged |
|
||||
| Content features | opportunities, preferences, AI-summary, consumption and debug factories/state | Filter/search storage round-trip, sorting, stale requests, AI safe text, plan/period controls, preserved labels and DOM | Existing DOM lifecycle and narrow-screen limitations remain |
|
||||
| Bootstrap, CSS and documentation | `content/main.js`, `background/main.js`, application roots, styles; README/docs | CSS byte-identical to original (hash test); factories connected, no orphan sources or peer-factory dependencies; old marker/eval fixture removed | Native browser matrix below remains pending |
|
||||
|
||||
The automated suites were run after the initial extraction and again after the
|
||||
platform/auth refinements, cleanup and final composition. Intermediate verification
|
||||
found and corrected test-harness expectations for source inventory and fixture
|
||||
callback messaging; no production auth, cookie or session policy was changed.
|
||||
|
||||
### Final Automated Verification
|
||||
|
||||
Executed with Node.js 24.19.0, directly through the package-script equivalents:
|
||||
|
||||
| Command | Result |
|
||||
| --- | --- |
|
||||
| `node scripts/build.mjs` | Both packages regenerated; all source/composed JavaScript syntax valid |
|
||||
| `node scripts/test.cjs` | All five suite files passed: AI, architecture (6 cases), characterization (22 cases), session recovery, consumption |
|
||||
| `node scripts/build.mjs --check` | Generated scripts/manifests match source composition |
|
||||
| `git diff --check` | No whitespace errors |
|
||||
|
||||
There is no configured linter. Syntax validation uses Node's JavaScript parser
|
||||
through vm.Script, not eval or new Function in the extension. No generators feature
|
||||
was located; standalone JavaScript generation therefore has no feature-specific
|
||||
snapshot to assert. The architectural suite verifies deterministic composition,
|
||||
source coverage, dependency injection, independent per-frame state and lazy
|
||||
localStorage failure handling. Feature suites use synthetic credentials only.
|
||||
|
||||
### UI Smoke Verification
|
||||
|
||||
The loopback fixture was exercised in the Codex in-app browser, using the same
|
||||
composed content factories with injected synthetic runtime/fetch/storage adapters.
|
||||
It is not an installed extension and does not validate privileged browser APIs.
|
||||
|
||||
- Paginated synthetic opportunities, product progress/counts and dashboard rendered.
|
||||
- Search text/filter remained after closing and reopening the modal.
|
||||
- Light/dark toggle and product expansion retained the existing presentation.
|
||||
- AI text, including literal HTML delimiters, appeared as text above the product table.
|
||||
- Preferences retained checkbox/cache-duration selections after Save and reopen.
|
||||
- Cloud Consumption opened with plan tabs; weekly default, daily switch, alternate
|
||||
plan and series visibility toggles worked. Debug listed scoped relay and AI calls.
|
||||
- Screenshots inspected at 1920x1080, 1280x720 and 390x844. Desktop columns rendered
|
||||
with complete Last Update Date and WON_PENDING. Existing compact-table scrolling
|
||||
and clipping at 1280 remain unchanged; mobile controls stack. This is not a full
|
||||
mobile workflow/accessibility audit and no layout redesign was included.
|
||||
- No console errors were reported during the exercised flows.
|
||||
|
||||
### Outstanding Native Browser Matrix
|
||||
|
||||
| Target | Package/runtime | Status |
|
||||
| --- | --- | --- |
|
||||
| Chrome | `dist/chromium`, MV3 service worker | Not run as an installed extension |
|
||||
| Edge | `dist/chromium`, MV3 service worker | Not run as an installed extension |
|
||||
| Firefox | `dist/firefox`, MV3 background scripts | Not run as an installed extension |
|
||||
|
||||
The available automation connection exposed the in-app browser and a Brave
|
||||
profile, not Chrome, Edge or Firefox. No live Fusion requests, user-session access
|
||||
or extension installation were used to substitute for the missing native tests.
|
||||
Actual suspension/reactivation, container routing and SSO remain unverified.
|
||||
|
||||
The next safe validation is to load the generated packages in an authorized test
|
||||
profile in each target browser, then exercise tile insertion, modal reopen,
|
||||
filters/preferences, products, AI, consumption, debug and background restart.
|
||||
Resolve the separately listed security issues only in explicitly approved changes.
|
||||
|
||||
See [the native browser checklist and execution record](browser-smoke.md) for the
|
||||
2026-09-17 follow-up. Local tests and output checks passed again; Chrome/Edge were
|
||||
installed but not connected to automation. Native verification remains pending
|
||||
while the user connects those browsers.
|
||||
Reference in New Issue
Block a user