Files
opportunities-extension/README.md

15 KiB

Opportunities Extension 1.0.1

Browser extension that adds the "Opportunities Extension" shortcut to the permitted Oracle Fusion pages, retrieves opportunities, and displays them in a filterable table.

Development Structure

  • src/content/: page integration, modal shell, theme and content composition.
  • src/background/: synchronous message registration and background composition.
  • src/features/: opportunities, products, consumption, AI summaries, preferences and debug.
  • src/auth/: credential-specific selection, reuse and session recovery.
  • src/services/: Fusion/SPA operations and background HTTP/JSON transport.
  • src/platform/: narrow browser messaging, cookies, tabs and storage adapters.
  • src/shared/messages.js: names of the existing cross-context messages.
  • scripts/build.mjs: generates browser-specific packages.
  • tests/: isolated synthetic regression tests and a visual fixture.
  • docs/: architecture/contracts and incremental refactoring record.
  • dist/chromium/: output for Google Chrome and Microsoft Edge.
  • dist/firefox/: output for Firefox.

CRM Service Request Badges

On the first Opportunities modal opening in a page session, requestCurrentUser fetches SPA identity before tokenrelay or opportunity requests. Concurrent calls, Reference changes and modal reopenings reuse that result. Users with SALES_REP do not trigger CRM Service Request or Workload Actions queries or see their badges. If identity or roles cannot be validated, only these two features stay disabled; other opportunity features continue. Reload the page to refresh identity/roles. The unused identity token is discarded and redacted from debug responses.

Once per opening of the opportunities modal, resquestCrmServiceRequest fetches all pages of CRMServiceRequest records with SVC_PENDING_DELIVERY and ORA_SVC_MY_SR_TEAM_SRS, using the existing general tokenrelay Bearer. It uses the Fusion searchResources/latest query endpoint, independently of the opportunity query version. Calls appear in the Service Requests debug category with masked credentials.

Records are linked by OpportunityName_Id_c.OptyNumber. A green SR badge indicates one or more matches; its tooltip lists each SR number, title, reported hours, owner, email and contact flags. A red badge indicates no match within that query's scope. A failed lookup shows SR ?, not a false no-match result, and opportunities still load. Badges follow Ramp Months and do not wait for product downloads. SR results remain in memory only. Reference changes share the in-flight lookup and reuse its result (including failures) without another request. Closing resets this state; reopening starts a fresh lookup, and responses from previous openings are ignored.

Workload Actions

Workload Actions are queried in the background after product results arrive, including cached products. Each distinct RevnId uses requestWlActions with the WWB-TS credential in Wwb-Provider-Authorization. The Act badge beside SR aggregates all products: green means an action's owner matches the general tokenrelay response's principal; red means no matching owner was found. Act ? means ownership could not be confirmed (including a missing principal). Tooltips retain all returned actions, regardless of owner. Principal stays in memory only. Queries are shared per modal opening (up to four concurrently), reused across Reference changes, and discarded on close. Reopening queries again. Only the first page is requested for now; hasNext is indicated in the tooltip. The debug panel groups these requests under Actions, with credentials masked.

Build

Use Node.js:

npm run build

The build updates dist/chromium and dist/firefox from the same source. It preserves the output directories and unchanged files, replacing changed files only after their complete contents have been written to a temporary file. Scripts are published before the manifest, avoiding missing or partially written scripts while an unpacked extension is loaded. Reload the extension and the Oracle page after updating; clear historical extension errors to check for new failures.

Do not edit files under dist directly. Both targets use Manifest V3, with a Chromium service worker and Firefox background scripts. The build composes classic factory modules from scripts/sources.cjs into one isolated IIFE per execution context. It serializes src/content/styles/redwood.css followed by the scoped src/features/debug/styles.css, src/features/opportunities/styles.css, src/features/install-base/styles.css, src/features/service-requests/styles.css src/features/consumption/plan-detail.css and src/features/ratecard/styles.css at build time. There is no runtime module loader, browser-side eval, ES-module requirement or new dependency.

Tests and Maintenance

Installed Base and Service Requests include a search input above their tables. Search filters loaded records across every displayed column, including raw and formatted numbers/dates, without additional API calls. Matching ignores case and accents; all whitespace-separated terms must match somewhere in the row. The result count updates as users type. Clearing the input restores all records; reopening a dialog starts with an empty search. Search remains available during loading and retains the entered terms when results arrive. Both themes are supported.

Each Cloud Consumption plan includes a Rate card button beside Contract ID. It opens an animated right-side drawer with skeleton rows, an all-column search and sortable headers. The drawer reuses the Cloud Consumption header component with the title Rate Card, customer subtitle, and the active plan's Booking Customer, Sold To Party Name, Contract ID, Header Status, Start Date and End Date. There is no separate plan-number subtitle or nested Rate Card action; its Close button dismisses only the drawer. requestRatecardByPlan sends the active plan's subPlanNum as the payload's planNumber, with recordsSize: 10000, to the fixed SPA endpoint. It uses the existing OCICONS-TS uiaasHeader.value in G2m-Authorization and is logged in the Consumption debug category with the existing credential masking. The eleven requested fields are displayed, including percentage discounts and USD prices with at least four decimal places. Search includes raw and formatted values; prices, quantities, percentages and dates sort by value. Only the drawer table scrolls, horizontally when its available width is below 1100px. Closing the drawer, changing plans or closing Cloud Consumption discards late UI updates. Concurrent requests for the same plan are shared; reopening after completion fetches again. Errors remain local. No new persisted cache, permissions, token refresh or retries are added. The provided contract requests up to 10000 records; the response's searchAfter is not used without a defined pagination contract. tests/ratecard.test.cjs covers transport, formatting, filtering, sorting and drawer lifecycle with synthetic responses and DOM, without launching browsers.

Cloud Consumption loads requestConsumptionPlanDetail for the active plan after account plans arrive, independently of the chart. Selecting another plan loads its subPlanNum on demand. The GET uses active=true and the raw OCICONS-TS uiaasHeader.value in G2m-Authorization, through the existing consumer session. Projection badges align with the chart container's left edge, while the Quarterly/Monthly/Weekly/Daily controls stay on the right of the same header row: red Forfeit, blue Overage. Hover or keyboard focus reveals an interactive tooltip; clicking pins it for access to the Order number links. Escape, Close, outside clicks, tab changes and modal closure dismiss it. Each root line retains its nested clines details. Only HTTPS order links on accountdashboard.oracle.com become clickable. Amounts use the requested non-LC fields, formatted without inferring a local currency. Details are kept only in the current modal, with in-flight deduplication and local loading/empty/error states. Failed details do not block the chart. The existing Consumption debug category includes this request.

The Service Requests action sits immediately after Installed Base below Customer. Its dialog opens with skeleton rows and lists open SRs for the selected customer. The background first calls requestAccountSummary with ACCP-TS, then uses its id (not registryId) in the GET requestCustomerServiceRequest URL. The SR credential is uiaasHeader.value from SPA-ORANGE, sent verbatim in custsr-auth, without a Bearer prefix, regardless of uiaasHeader.label. Pages of 40 are consolidated using totalResults, count and offset. Concurrent clicks for the same customer share the in-flight query; results are not cached, and closed/replaced dialogs ignore late responses. The table maps Name/Registry ID from customer, Product Name from component, and formats status as a badge and dates using the existing date formatter. Debug contains a Service Requests category; credential headers are masked before delivery to content. This feature adds no permissions or authentication retries.

The Installed Base action sits beside customer consumption below Customer. It opens a skeleton dialog, then calls requestAccountSummary with ACCP-TS and uses the returned registryId in requestInstallBase. The latter uses the SAIB-TS uiaasHeader.label and uiaasHeader.value, and loads pages of 25 until hasMore is false. Missing credentials, invalid collections and stalled pagination show an error rather than partial results. These requests appear in debug; credential headers in this flow are masked before delivery to the content script. No new cache, permissions or session recovery logic is introduced. Amounts use two decimal places without inferring a currency from the separate LC fields.

The opportunities table places product counts below Name and the customer consumption action below Customer, without a separate Actions column. Compact columns retain their values; Name and Customer share the remaining width while Owner is fixed at 132px. Both text cells reserve at least two text lines, and their controls stay anchored 10px above the row bottom, including while products load. Longer text can grow the row without overlapping controls. Horizontal scrolling is reserved for table containers below 1120px. The scoped table stylesheet does not change product-table column widths or the existing light/dark colors.

Product HTTP requests appear in Debug Requests (Ctrl+D) as soon as they start. Each entry identifies the opportunity and page offset, stays running while waiting for headers or the response body, and updates with HTTP status, response, duration or error. Cache hits do not create HTTP entries. Product diagnostics mask authorization and sensitive response headers before messaging the source tab/frame; this change adds no timeout, retry or authentication behavior.

Debug Requests opens as a full-page view inside the extension using Ctrl+D, without opening a browser tab or entering native browser fullscreen. Close, Escape or Ctrl+D returns to the underlying view. Header/category navigation remains above the scrollable timeline; expanded details use two columns on wide screens and one on narrow screens. Theme-specific colors distinguish success, failure, running, HTTP methods/statuses, request/response sections and JSON tokens. Highlighting uses safe text nodes only after the existing sensitive-value masking. Compact JSON, supported protection prefixes and JSON documents wrapped in strings are normalized and indented, including while sensitive values are visible. Large JSON responses are captured as bounded, valid JSON previews with an explicit omission notice, preserving indentation, highlighting and sensitive-field masking. Already incomplete or invalid JSON remains plain text. The visibility toggle retains its existing behavior. Focus, expansion and timeline scroll position survive log updates.

Debug tabs group Authentication, Opportunities, Products, AI, Consumption, Installed Base and Service Requests requests; unknown request types appear under Other. Only categories with entries are shown. All preserves the complete timeline. Every tab sorts by request start time, retaining original request IDs and showing start times in collapsed rows. Counts and running states update without changing the selected category or collapsing expanded details. Use arrow keys, Home and End to navigate the tabs.

npm test
npm run check

Tests use built-in Node.js modules and synthetic credentials, without real Fusion requests. The characterization suite verifies manifests, source/output equality, fiscal dates, payloads, preferences, pagination, cache/progress and both browser API styles. Architecture tests enforce source inclusion, explicit factory dependencies, isolated state and unchanged CSS. These complement consumption, session recovery and AI suites. check also fails if generated packages are stale. There is no separate lint configuration or runtime dependency installation.

See architecture and contracts and the incremental refactoring record for execution boundaries, authentication, storage, known risks and verification limits. Mock-based tests do not replace testing the installed extension in each browser.

Without npm, run node scripts/build.mjs, node scripts/test.cjs and node scripts/build.mjs --check. Development checks were run with Node 24.19.0.

For a local UI smoke test, run node scripts/preview.mjs and open the loopback URL printed by the command. The fixture uses synthetic opportunities, tokens, products, AI text and consumption; unexpected requests fail closed. It does not authenticate against Fusion or read real extension storage. /consumption-trend.html provides a focused chart fixture. Stop the server with Ctrl+C when finished.

Release 1.0.0

  • Paginated opportunity retrieval with filters for reference, customer, owner, status, stage, and text search.
  • Column sorting, links to opportunities and accounts, opportunity number copying, and stage indicators.
  • Opportunity type view preferences persisted in the browser.
  • Background product retrieval with configurable caching, progress tracking, and expandable product details.
  • Cloud consumption account-plan lookup from each opportunity, displayed in a tabbed detail modal.
  • Light and dark themes based on Oracle Redwood.
  • Separate outputs for Chromium/Edge and Firefox.

Release 1.0.1

  • Retries the consumer token service when it returns HTTP 200 with an HTML fallback.
  • Opens the SPA session page in an inactive temporary tab and closes it as soon as valid JSON is received.
  • Limits the recovery flow to five attempts and records the session bootstrap details in debug mode.

Loading in Development Mode

Chrome or Microsoft Edge

  1. Open chrome://extensions or edge://extensions.
  2. Enable Developer mode.
  3. Click Load unpacked.
  4. Select the dist/chromium folder.

Firefox

  1. Open about:debugging#/runtime/this-firefox.
  2. Click Load Temporary Add-on.
  3. Select the dist/firefox/manifest.json file.

Supported Pages

  • https://eeho.fa.us2.oraclecloud.com/hcmUI/faces/FuseWelcome
  • https://eeho.fa.us2.oraclecloud.com/fscmUI/faces/FuseWelcome

When it finds the #yourapps_groupNode_sales group, the extension adds the tile before the .flat-grid-cell.flat-grid-cell-addicon item. Clicking the tile opens the opportunities interface.