Implemented OpenSpec and created and updated its artifacts
This commit is contained in:
0
openspec/changes/archive/.gitkeep
Normal file
0
openspec/changes/archive/.gitkeep
Normal file
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-10-31
|
||||
@@ -0,0 +1,166 @@
|
||||
# Design
|
||||
|
||||
## Context
|
||||
|
||||
See proposal.md for motivation and the capability inventory. This is the initial specification baseline for the current checkout, whose package/build version is 1.1.0. The checkout includes behavior added after the 1.1.0 release; the baseline must not be presented as an exact description of that tag.
|
||||
|
||||
OpenSpec uses the existing `spec-driven` schema. Its main specification directory is empty. The change introduces behavioral contracts, not runtime features. A design is warranted because reconciling documentation spans authentication, data loading, storage and UI boundaries and requires explicit decisions about conflicting historical descriptions.
|
||||
|
||||
The application uses factory-based JavaScript modules. `src/content/application.js` and `src/background/application.js` compose collaborators; `scripts/sources.cjs` and `scripts/compose.cjs` assemble isolated classic scripts. `scripts/build.mjs` generates Manifest V3 distributions for Chromium/Edge and Firefox with different background entry points. No framework migration is involved.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Preserve externally observable behavior in requirements with testable scenarios.
|
||||
- Make source/test evidence discoverable without putting internal function names into normative requirements.
|
||||
- Reconcile README and architecture descriptions with current behavior during application.
|
||||
- Establish the distinction between a proposed baseline in this change and durable specifications promoted after review and completion.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- Fix unrelated runtime defects, add retries, migrate storage, alter permissions or change endpoints.
|
||||
- Declare every scenario already covered by automated or live-browser tests.
|
||||
- Copy the full README into configuration, customize the OpenSpec schema, or add machine-specific executable paths as project requirements.
|
||||
- Change release history, regenerate packages for documentation edits, or publish a version.
|
||||
|
||||
## Decisions
|
||||
|
||||
### 1. Bootstrap existing capabilities explicitly
|
||||
|
||||
The specs use `ADDED Requirements` because the OpenSpec inventory is empty. This means new specification coverage, not newly implemented product behavior. Each spec has its own Purpose and cohesive domain boundary. A documentation-only `skip_specs` change would not fulfill the user's request to establish functional artifacts, while a single all-project spec would make future deltas difficult to review.
|
||||
|
||||
### 2. Resolve documentation conflicts against observable implementation
|
||||
|
||||
Use current source plus relevant regression scenarios to determine the baseline. Historical release notes explain evolution; they do not override the current implementation. Tests are supporting evidence, not proof of live Oracle compatibility. Unverified aspirations must not be silently converted into requirements or implemented during baseline application.
|
||||
|
||||
### 3. Preserve runtime and storage distinctions
|
||||
|
||||
Document content/background messaging and browser API adaptation without changing them. Distinguish page localStorage, sessionStorage, extension storage, in-memory caches and extension-owned IndexedDB. In particular, debug display masking does not guarantee that stored records exclude credentials. A blanket statement that all production credentials remain only in memory would contradict the retained debug response behavior.
|
||||
|
||||
The principal flow to describe is:
|
||||
|
||||
```text
|
||||
identity and session preparation
|
||||
|
|
||||
v
|
||||
Token Relay --> Opportunity saved search --> opportunity pages
|
||||
|
|
||||
v
|
||||
display ready list
|
||||
|
|
||||
+-------------------------+------------------+
|
||||
v v
|
||||
CRM SR background pages product enrichment
|
||||
| |
|
||||
+-------- SR success/reuse + products -------+
|
||||
|
|
||||
v
|
||||
Workload Actions
|
||||
```
|
||||
|
||||
Workloads additionally depend on account/product identifiers. This diagram does not prescribe a new global request scheduler. Profile gates apply to the data operations they control; concurrent session bootstrap is not itself a Manage Time data request.
|
||||
|
||||
### 4. Keep documentation responsibilities separate
|
||||
|
||||
- README.md: concise product overview, supported entry points, major features, development/build/test/loading instructions and links to deeper documentation.
|
||||
- docs/architecture.md: execution contexts, transport/credential boundaries, storage ownership, actual permissions and verification limits.
|
||||
- RELEASE_NOTES.md: historical release record; preserve prior descriptions as history rather than rewriting old releases to match today.
|
||||
- `openspec/specs/`: durable behavioral contracts after the baseline is reviewed, applied and archived.
|
||||
- This change: proposal, design, initial delta specs and actionable documentation/verification tasks.
|
||||
|
||||
Replacing the README entirely with OpenSpec would make ordinary setup less accessible. Duplicating complete behavioral contracts in both places would make future drift more likely. Link from documentation instead, retaining only the usage detail needed by its audience.
|
||||
|
||||
### 5. Use minimal configuration
|
||||
|
||||
Retain `openspec/config.yaml` as initialized. Discoverable code structure and local CLI locations do not need to become project context rules. All artifacts in this change are English to match the extension documentation; discussion with the user remains Portuguese. Any later configuration customization is a separate explicit decision.
|
||||
|
||||
## Evidence Map
|
||||
|
||||
Paths below are relative to the repository root. These identify where to review behavior, not a claim that every specification scenario has already been executed.
|
||||
|
||||
| Capability | Primary source evidence | Existing regression evidence |
|
||||
| --- | --- | --- |
|
||||
| session-authentication | `src/auth/current-user.js`, `src/auth/consumer-session.js`, `src/auth/spa-page.js`, `src/background/contracts.js`, `src/content/application.js` | `tests/currentUser.test.cjs`, `tests/spaSessionWait.test.cjs`, `tests/spaSessionReload.test.cjs`, `tests/srSessionPreparation.test.cjs` |
|
||||
| opportunity-exploration | `src/services/fusion/opportunities.js`, `src/features/opportunities/controller.js`, `filters.js`, `table.js`, `fiscal-periods.js` | `tests/dependentFilters.test.cjs`, `tests/allOpportunityFilters.test.cjs`, `tests/opportunityTable.test.cjs`, `tests/dashboardTotals.test.cjs`, `tests/characterization.test.cjs` |
|
||||
| opportunity-calendar | `src/features/opportunities/calendar.js`, `src/features/opportunities/styles.css` | `tests/opportunityCalendar.test.cjs` plus installed-browser visual inspection for week positioning |
|
||||
| product-workloads | `src/features/products/details.js`, `workloads.js`, `workloads-cache.js`, `ramp-projection.js`, `forecast-update.js` | `tests/workloads.test.cjs`, `tests/ramp-projection.test.cjs`, `tests/workload-forecast-update.test.cjs`, `tests/badgeIcons.test.cjs` |
|
||||
| service-requests | `src/services/fusion/crm-service-requests.js`, `src/features/opportunities/crm-service-requests.js`, `crm-sr-form.js`, `internal-sr-session.js`, `internal-sr-form.js`, `src/features/service-requests/` | `tests/srRequestPriority.test.cjs`, `tests/crmServiceRequests.test.cjs`, `tests/activityProgress.test.cjs`, `tests/internalSrRecovery.test.cjs`, `tests/srCreate.test.cjs`, `tests/serviceRequests.test.cjs` |
|
||||
| workload-actions | `src/features/opportunities/product-activities.js`, `workload-actions.js`, `workload-action-form.js` | `tests/productActivities.test.cjs`, `tests/workloadActions.test.cjs`, `tests/workloadActionForm.test.cjs` |
|
||||
| manage-time | `src/features/manage-time/view.js`, `src/services/fusion/time-entries.js`, `src/content/application.js` | `tests/manageTime.test.cjs`, `tests/currentUser.test.cjs` |
|
||||
| customer-insights | `src/features/install-base/`, `src/features/consumption/`, `src/features/ratecard/`, `src/services/spa/` | `tests/installBase.test.cjs`, `tests/consumptionTrend.test.cjs`, `tests/consumptionPlanDetail.test.cjs`, `tests/ratecard.test.cjs` |
|
||||
| organization-charts | `src/features/org-chart/model.js`, `storage.js`, `view.js`, `src/services/fusion/account-contact.js` | `tests/orgChart.test.cjs`, `tests/accountContact.test.cjs` |
|
||||
| extension-shell | `src/content/fusion-page.js`, `shortcut-intent.js`, `modal.js`, `dialog-drag.js`, `src/features/opportunities/print.js` | `tests/shortcutLink.test.cjs`, `tests/bookmarkShortcut.test.cjs`, `tests/bookmarkHint.test.cjs`, `tests/modalShortcuts.test.cjs`, `tests/dialogDrag.test.cjs` |
|
||||
| preferences-cache | `src/features/preferences/`, `src/features/opportunities/activity-cache.js`, `refresh-all.js`, `src/features/products/cache.js` | `tests/tableSorting.test.cjs`, `tests/activityCache.test.cjs`, `tests/formRequestCache.test.cjs`, `tests/refreshAll.test.cjs` |
|
||||
| request-debugging | `src/features/debug/state.js`, `content-log.js`, `content-view.js`, `src/services/fusion/opportunities.js` | `tests/debugStorage.test.cjs`, `tests/debugTabs.test.cjs`, `tests/productsDebug.test.cjs` |
|
||||
|
||||
## Documentation Reconciliation
|
||||
|
||||
During application, make the following concrete corrections, verifying the cited implementation again before editing:
|
||||
|
||||
| Document/topic | Required reconciliation |
|
||||
| --- | --- |
|
||||
| README Opportunity Views | Replace month/week navigation and overflow links with Reference-bounded scrolling months, all daily cards and current-week positioning. |
|
||||
| README and architecture AI references | Remove descriptions of active AI summaries, Sales Common token acquisition and AI suites/modules. Preserve historical release notes. |
|
||||
| README authentication | Use the current SPA UI bootstrap URL; distinguish successful identity reuse from session recovery attempts. |
|
||||
| README SR/Actions ordering | Describe opportunities displayed first, progressive SR enrichment and Actions depending on product identifiers and SR success/reuse. Remove the assertion that SR must wait for product completion. |
|
||||
| README activity cache | Reconcile claims that cached products never allow activity network requests: the current product-activity orchestration permits cache-miss lookups. Retain timestamp/principal cache scoping where implemented. |
|
||||
| README access restrictions | Include Manage Time UI and data gates for SALES_REP. Do not claim that all independent SR session bootstrap is disabled by that role. |
|
||||
| README Organization Charts | Include alphanumeric PartyNumber, on-demand contact refresh, transient email, contact creation and fully paginated contact opportunities. |
|
||||
| README capabilities | Cover dependent Customer/Owner options, Booking/Workload filters, printing, bookmark shortcuts/hints and draggable headers. |
|
||||
| README Rate Card | Document Order Number multiselect and inspect final composed styles before describing responsive width; a single earlier CSS min-width rule is not proof of the effective layout. |
|
||||
| Architecture contexts/permissions | Reflect the early shortcut-intent script, SPA readiness script and generated manifest permissions/hosts from `scripts/build.mjs`, including bookmarks and SR integration access. |
|
||||
| Architecture request lifecycle | Remove the blanket claim that no AbortController is used; distinguish Token Relay timeouts from stale-response suppression and requests continuing behind a hidden modal. |
|
||||
| Architecture storage | Describe debug localStorage and its reset boundary, preferences/sort storage, activity/product/workload caching, identity/session reuse and org-chart IndexedDB. Distinguish UI masking from storage confidentiality. |
|
||||
| Architecture legacy contracts | Remove active RENEWALS and AI contracts; explain dynamic saved-search selection for Opportunity and CRM SR independently. |
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [A baseline can accidentally promise unimplemented behavior] -> Trace each requirement to source and scenarios; raise discrepancies rather than adding runtime fixes under this documentation change.
|
||||
- [Documentation already contains contradictory cache and session claims] -> Review the composition root and effective call paths, not just an isolated helper or old prose.
|
||||
- [Synthetic tests cannot verify Oracle endpoint availability or browser SSO] -> Record automated validation separately from installed-browser/live-service verification; never label the latter passed without execution.
|
||||
- [Debug records can contain sensitive values] -> Describe the current behavior accurately without embedding real tokens, customer responses or personal data in artifacts. Any storage-hardening change is separate work.
|
||||
- [Broad baseline coverage can obscure ownership] -> Keep twelve cohesive capability files and a source/test evidence map; do not duplicate implementation details in requirements.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Review the proposed contracts against the current checkout and resolve documentation discrepancies without changing runtime behavior.
|
||||
2. Apply the README and architecture corrections; keep the existing principal README title and separate release history.
|
||||
3. Validate the OpenSpec change strictly, verify build consistency and run the relevant existing synthetic checks. Record any failures or browser-verification gaps honestly.
|
||||
4. Complete the documentation tasks, then use the archive workflow to promote the initial specs to `openspec/specs/`. Do not manually copy them early or mark the change applied merely because planning is complete.
|
||||
5. For subsequent behavior changes, identify the affected baseline capability, create delta requirements, implement and verify, then archive.
|
||||
|
||||
No runtime deployment or data migration is required. Before archival, rollback consists of reverting the documentation edits and removing the proposed change through an explicit repository operation. After archival, restore/revise documentation and specifications together through a follow-up change; never delete user data or rewrite release history as part of this baseline.
|
||||
|
||||
## Application Review Record
|
||||
|
||||
Reviewed on 2026-10-31 against the current checkout:
|
||||
|
||||
- All twelve proposed capabilities have a matching specification file. Structural review found 69 requirements and 88 scenarios; every requirement has a scenario with a trigger and outcome.
|
||||
- README.md and docs/architecture.md now distinguish opportunity-first loading, background SR progress, product-dependent Actions and cache-miss activity reads from the superseded loading descriptions.
|
||||
- The documentation distinguishes page storage, extension storage and chart IndexedDB; it explicitly states that debug masking does not remove retained originals from storage.
|
||||
- Review confirmed the current SPA bootstrap, role gates, dynamic saved searches, contact identifiers and composed Rate Card styles without changing their implementation. No additional runtime behavior was introduced to satisfy the baseline.
|
||||
- Task-specific synthetic suites passed as their documentation groups were applied. Local documentation links resolve.
|
||||
- No installed-browser visual test or live Oracle authentication/read/write was performed. Calendar sizing, responsive layouts, dragging, print pagination and live endpoint availability retain that verification limitation; synthetic scenario coverage is not a claim of end-to-end certification.
|
||||
|
||||
Final application checks on 2026-10-31:
|
||||
|
||||
- `openspec validate document-project-baseline --strict`: passed.
|
||||
- `node scripts/build.mjs --check`: passed; existing Chromium/Edge and Firefox outputs match the source.
|
||||
- `node scripts/test.cjs` using Node 22.15.0: 54 test files, 462 tests passed, zero failed.
|
||||
- `git diff --check` and a whitespace scan of the new OpenSpec Markdown files: passed.
|
||||
- The tracked diff contains only README.md and docs/architecture.md. The change's task/review records are updated in the already-created OpenSpec tree; the preexisting untracked `.agents/` installation is untouched.
|
||||
- Source, tests, build scripts, distributions, package version, release history and OpenSpec configuration are unchanged. The change is applied but not archived; the main spec inventory remains unpopulated until the separate archive workflow.
|
||||
|
||||
## Archive Record
|
||||
|
||||
On 2026-10-31, after explicit approval to synchronize and archive, all twelve
|
||||
capabilities were promoted to `openspec/specs/`. Their authored Purpose sections,
|
||||
69 requirements and 88 scenarios were preserved; the main files use canonical
|
||||
Specification titles and Requirements sections without delta-operation headers.
|
||||
All twelve main specifications passed `openspec validate --specs --strict`.
|
||||
The completed change (13/13 tasks, schema `spec-driven`) was moved to
|
||||
`openspec/changes/archive/2026-10-31-document-project-baseline/`, including its
|
||||
`.openspec.yaml`. README and architecture navigation now point to the durable
|
||||
specifications and archived evidence. This archive record supersedes the
|
||||
pre-archive inventory status in the application checks above.
|
||||
@@ -0,0 +1,41 @@
|
||||
# Proposal
|
||||
|
||||
## Why
|
||||
|
||||
OpenSpec has been initialized without capability specifications, while the README and architecture document still describe several superseded behaviors. Establish an evidence-backed baseline so future changes can state precisely which existing contracts they preserve or modify.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Introduce initial specifications for existing behavior, using the current source and regression tests as evidence. These are new OpenSpec records, not new product features.
|
||||
- Record authentication boundaries, asynchronous loading order, role restrictions, persistence, and user interactions as requirements with observable scenarios.
|
||||
- Plan corrections to README.md and docs/architecture.md, including Calendar, removed AI summaries, SPA navigation, SR loading, Manage Time access, contact identifiers, permissions, and debug storage.
|
||||
- Keep README.md as the product/development entry point and RELEASE_NOTES.md as release history. Link durable behavior to OpenSpec after the baseline is applied and archived.
|
||||
- Distinguish verified code behavior, synthetic test coverage, and live-browser verification still required. Do not treat historical requests or old documentation as implemented behavior.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `session-authentication`: Identity acquisition/reuse, SPA/SR session recovery, credential routing and profile gates.
|
||||
- `opportunity-exploration`: Saved-search queries, pagination, fiscal Reference, coordinated filters, table sorting and indicators.
|
||||
- `opportunity-calendar`: Reference-bounded monthly scrolling, daily cards, fiscal labels and current-week positioning.
|
||||
- `product-workloads`: Product enrichment, workload caching, Booking classification, projections and forecast updates.
|
||||
- `service-requests`: Progressive CRM SR enrichment, saved-search lookup, customer/internal SR details and creation.
|
||||
- `workload-actions`: Ownership badges, dependent loading, action metadata and validated creation.
|
||||
- `manage-time`: Weekly entry viewing/editing, task selection, validation and explicit writes.
|
||||
- `customer-insights`: Installed Base, consumption plans/trends/details and Rate Card exploration.
|
||||
- `organization-charts`: Local hierarchy storage, contact lookup/creation and opportunities by contact.
|
||||
- `extension-shell`: Fusion entry points, bookmarks, keyboard shortcuts, modal interaction and printing.
|
||||
- `preferences-cache`: Persistent preferences, sorting and cache invalidation boundaries.
|
||||
- `request-debugging`: Request capture, lazy rendering, history lifetime and sensitive-value visibility.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
None. The existing OpenSpec specification inventory is empty.
|
||||
|
||||
## Impact
|
||||
|
||||
- Planning artifacts are confined to `openspec/changes/document-project-baseline/`.
|
||||
- Subsequent application updates README.md and docs/architecture.md; successful archive promotes the reviewed baseline to `openspec/specs/`.
|
||||
- Source, generated distributions, API contracts, browser permissions, dependencies, storage formats and version 1.1.0 remain unchanged by this documentation effort.
|
||||
- No release, tag, commit, live Oracle write, new authentication behavior, or OpenSpec schema/configuration customization is included.
|
||||
@@ -0,0 +1,51 @@
|
||||
## Purpose
|
||||
|
||||
Provide customer-specific Installed Base and consumption exploration without disrupting the main opportunity view.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Installed Base uses the registry identifier
|
||||
Installed Base SHALL first resolve account summary and query using its `registryId` with the SAIB authorization. It SHALL continue pagination until `hasMore=false`, and reject invalid or stalled pages instead of presenting a partial list as complete.
|
||||
|
||||
#### Scenario: More installed items exist
|
||||
- **WHEN** an Installed Base page returns `hasMore=true`
|
||||
- **THEN** subsequent pages are loaded before the complete result is presented
|
||||
|
||||
### Requirement: Installed Base avoids duplicate customer presentation
|
||||
Installed Base SHALL show the customer in the modal header, omit the Customer column, and provide searchable sortable data with loading skeletons.
|
||||
|
||||
#### Scenario: User searches installed items
|
||||
- **WHEN** search text is entered
|
||||
- **THEN** loaded rows and the result count update locally without another account query
|
||||
|
||||
### Requirement: Consumption follows the selected plan
|
||||
Customer consumption SHALL resolve available account plans and load trends for the selected plan with quarterly, monthly, weekly and daily periods. Plan detail loading SHALL be independent of trend loading and failed details SHALL not block the chart.
|
||||
|
||||
#### Scenario: User switches plans
|
||||
- **WHEN** the selected plan changes while an earlier plan request is pending
|
||||
- **THEN** late results from the earlier plan do not replace the selected plan's view
|
||||
|
||||
### Requirement: Projection details preserve safe order navigation
|
||||
Consumption plan details SHALL expose Forfeit and Overage information with nested line details in interactive tooltips. Only HTTPS order links on `accountdashboard.oracle.com` SHALL be clickable.
|
||||
|
||||
#### Scenario: Unsafe order URL
|
||||
- **WHEN** a returned order URL uses a different host or unsupported scheme
|
||||
- **THEN** the detail remains readable without offering that URL as a clickable order link
|
||||
|
||||
### Requirement: Rate Card queries the active plan
|
||||
Rate Card SHALL query using the selected plan's `subPlanNum` and OCICONS authorization, show plan/customer context and provide search, sorting and multi-selection of distinct Order Numbers. The current request SHALL use a 10000-record limit without implying unsupported cursor pagination.
|
||||
|
||||
#### Scenario: Order filter isolates one choice
|
||||
- **WHEN** all order numbers are selected and the user clicks one order
|
||||
- **THEN** only that order remains selected and search continues to combine with the order filter
|
||||
|
||||
#### Scenario: Rate Card closes while loading
|
||||
- **WHEN** the drawer closes before its request completes
|
||||
- **THEN** the late result does not reopen or overwrite a different active plan view
|
||||
|
||||
### Requirement: Customer tables sort and search by meaningful values
|
||||
Customer table search SHALL match case-insensitively and accent-insensitively across displayed values. Sorting SHALL use numeric or date values where applicable, and restore each supported table's saved ordering.
|
||||
|
||||
#### Scenario: Numeric amount ordering
|
||||
- **WHEN** the user sorts a customer table by a monetary column
|
||||
- **THEN** rows are ordered by numeric amount rather than by the formatted text
|
||||
@@ -0,0 +1,47 @@
|
||||
## Purpose
|
||||
|
||||
Provide predictable entry points, navigation, modal interaction and printing across the supported browser extension targets.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Supported Fusion pages expose the extension
|
||||
The extension SHALL provide its entry tile on the configured Oracle Fusion hcmUI and fscmUI FuseWelcome pages. A bookmarked URL with the extension shortcut marker SHALL open the main modal without requiring a click on the Sales group.
|
||||
|
||||
#### Scenario: Fusion rewrites the URL
|
||||
- **WHEN** the user follows the shortcut URL and Fusion subsequently replaces its query string
|
||||
- **THEN** the captured shortcut intent still permits the extension to open once when ready
|
||||
|
||||
### Requirement: Favorites use an explicit folder choice
|
||||
Ctrl+Shift+F within the extension SHALL open a searchable browser-bookmark folder picker. Saving SHALL use the chosen writable folder and extension shortcut URL rather than silently choosing an arbitrary location.
|
||||
|
||||
#### Scenario: User selects a bookmark folder
|
||||
- **WHEN** the user confirms a writable folder and saves
|
||||
- **THEN** the extension shortcut is saved in that folder
|
||||
|
||||
### Requirement: Bookmark discovery keeps Last update first
|
||||
When the shortcut is not bookmarked, the header SHALL show a prominent shortcut hint for 20 seconds. Last update SHALL remain the first badge and other badges SHALL appear to its right.
|
||||
|
||||
#### Scenario: Favorite is saved while the hint is visible
|
||||
- **WHEN** the shortcut is successfully added to bookmarks
|
||||
- **THEN** the favorite hint is removed without waiting for the remaining timeout
|
||||
|
||||
### Requirement: Non-full-page modals can be dragged by their header
|
||||
Non-full-page modals SHALL support dragging from noninteractive areas of their title bar, allowing up to 70 percent of their width and height beyond viewport edges. Header controls SHALL retain their own interactions and full-page views SHALL not become draggable.
|
||||
|
||||
#### Scenario: Drag exceeds viewport edge
|
||||
- **WHEN** the user drags a movable modal far outside the viewport
|
||||
- **THEN** movement is clamped so at least 30 percent of each modal dimension remains within the allowed bounds
|
||||
|
||||
### Requirement: Shared presentation remains consistent
|
||||
Modal titles, spacing, loading skeletons and table presentation SHALL follow the extension's shared visual patterns in light and dark themes. User-facing labels SHALL use English, with service-provided names preserved.
|
||||
|
||||
#### Scenario: Customer detail is opened while loading
|
||||
- **WHEN** the user opens a customer table before its data arrives
|
||||
- **THEN** its title and loading skeleton use the shared modal styling
|
||||
|
||||
### Requirement: Print output reflects the current opportunity view
|
||||
The print action beside Booking/Workload filters SHALL produce a landscape-oriented browser print layout containing active filter summaries, indicators and the opportunity list with page padding.
|
||||
|
||||
#### Scenario: All customers and owners are selected
|
||||
- **WHEN** the user opens the print layout with unrestricted Customer and Owner selections
|
||||
- **THEN** it labels them `All customers` and `All owners` instead of expanding every selected name
|
||||
@@ -0,0 +1,51 @@
|
||||
## Purpose
|
||||
|
||||
Let authorized users review and maintain weekly time entries with validated hours and explicit, traceable persistence.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Manage Time requires profile and session readiness
|
||||
Manage Time SHALL remain unavailable to `SALES_REP` users. For eligible users, its launcher SHALL remain disabled until SR session readiness, and data request entry points SHALL enforce the profile gate before loading time data.
|
||||
|
||||
#### Scenario: Restricted profile with a ready session
|
||||
- **WHEN** SR session preparation succeeds for a user with `SALES_REP`
|
||||
- **THEN** Manage Time remains hidden and opening it does not send its data requests
|
||||
|
||||
### Requirement: Week navigation preserves the user's work
|
||||
Manage Time SHALL restore its selected reference date, navigate in seven-day increments and retain local drafts while moving between weeks within the modal. Late responses for a different week or closed modal SHALL not replace active values.
|
||||
|
||||
#### Scenario: Navigate away and back
|
||||
- **WHEN** the user edits an unsaved week, navigates to another week and returns
|
||||
- **THEN** the earlier week's local edits remain available
|
||||
|
||||
### Requirement: Entry selections are dependent and searchable
|
||||
Service Request, Activity and Task Type selections SHALL support autocomplete. Activities SHALL correspond to the chosen SR, task types SHALL match Service or Non Service rows, and duplicate SR selection SHALL be rejected with row feedback.
|
||||
|
||||
#### Scenario: Duplicate SR
|
||||
- **WHEN** a user selects an SR already used by another row
|
||||
- **THEN** the previous selection is restored and the existing row is highlighted
|
||||
|
||||
### Requirement: Hours are validated before persistence
|
||||
Each entered daily hour value SHALL be numeric and within the inclusive range 0 through 24. The view SHALL show daily totals and reject invalid rows before any affected write.
|
||||
|
||||
#### Scenario: Invalid daily hours
|
||||
- **WHEN** a user attempts to save a row containing 25 hours for one day
|
||||
- **THEN** validation prevents that invalid time entry from being submitted
|
||||
|
||||
### Requirement: Save controls creation updates and deletions
|
||||
Save SHALL create new entries with POST, update changed persisted entries with PUT and apply queued persisted deletions with DELETE. Removing an unsaved row SHALL remain local. Writes SHALL use the required session and current-resource context.
|
||||
|
||||
#### Scenario: Persisted row is removed before Save
|
||||
- **WHEN** a user removes a persisted row without saving
|
||||
- **THEN** the deletion remains queued and no DELETE is sent yet
|
||||
|
||||
#### Scenario: Partial save failure
|
||||
- **WHEN** some entry operations succeed and another operation fails
|
||||
- **THEN** successful results remain reflected locally and unfinished work remains available for retry without duplicating confirmed writes
|
||||
|
||||
### Requirement: Loading and failures are local to the time view
|
||||
Manage Time SHALL display skeleton rows while loading and provide retry on data failure without discarding the user's current draft values.
|
||||
|
||||
#### Scenario: Week retrieval fails
|
||||
- **WHEN** the active week's request fails
|
||||
- **THEN** the modal exposes the failure and retry while protecting existing edits
|
||||
@@ -0,0 +1,44 @@
|
||||
## Purpose
|
||||
|
||||
Present the filtered opportunities by close date in a vertically navigable calendar bounded by the chosen Reference.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Calendar is a Reference-bounded monthly view
|
||||
Calendar SHALL show a continuous monthly view restricted to the selected Reference, with vertical scrolling and no month/week switch or previous/next navigation buttons. Switching between Overview and Calendar SHALL not fetch opportunities again.
|
||||
|
||||
#### Scenario: Reference spans multiple months
|
||||
- **WHEN** the user opens Calendar for a multi-month Reference
|
||||
- **THEN** all months in the Reference remain reachable by vertical scrolling, including months with no opportunities
|
||||
|
||||
### Requirement: Every daily opportunity has a card
|
||||
Each day SHALL show cards for all matching opportunities with a scrollable daily region when necessary. A hidden-event overflow link SHALL not replace the extra cards.
|
||||
|
||||
#### Scenario: Many opportunities close on one day
|
||||
- **WHEN** the day's cards exceed its available height
|
||||
- **THEN** the user can scroll within the day to reach all cards and the count reflects all matching opportunities
|
||||
|
||||
### Requirement: Initial positioning includes adjacent weeks
|
||||
When today is within Reference, Calendar SHALL position around the current week and adjust visible week sizing to include the preceding and following weeks where the Reference permits. Dates outside Reference SHALL remain excluded.
|
||||
|
||||
#### Scenario: Current week crosses a month boundary
|
||||
- **WHEN** Calendar positions around today and the three-week interval crosses into another month
|
||||
- **THEN** the rendered portions of those weeks are included in the positioning calculation
|
||||
|
||||
### Requirement: Dates retain their calendar-day meaning
|
||||
Calendar SHALL use `EffectiveDate` as a date-only close date without timezone shifts. Opportunities with missing or invalid close dates SHALL remain available in a separate list, and fiscal week labels SHALL use Sunday-start weeks and a June-start fiscal year.
|
||||
|
||||
#### Scenario: API date includes an offset
|
||||
- **WHEN** an opportunity close date contains a timezone offset
|
||||
- **THEN** its card retains the API calendar day instead of shifting to an adjacent day
|
||||
|
||||
#### Scenario: Missing close date
|
||||
- **WHEN** a filtered opportunity has no valid close date
|
||||
- **THEN** it is accessible through the undated-opportunities list
|
||||
|
||||
### Requirement: Calendar details are read-only
|
||||
Opportunity cards SHALL show stage information and open read-only details with the corresponding opportunity link. Calendar labels and controls SHALL be in English.
|
||||
|
||||
#### Scenario: User selects a card
|
||||
- **WHEN** an opportunity card is clicked
|
||||
- **THEN** its details are shown without changing the opportunity in Oracle
|
||||
@@ -0,0 +1,63 @@
|
||||
## Purpose
|
||||
|
||||
Let users explore Oracle opportunities within a fiscal Reference using consistent filters, totals and sortable tabular data.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Queries use the user's default saved search
|
||||
Opportunity queries SHALL resolve the unique saved search marked `isDefault=true` and use its `savedSearchNumber` in `copiedFrom` for every page. Missing or ambiguous default searches SHALL prevent a dependent opportunity query.
|
||||
|
||||
#### Scenario: Valid default search
|
||||
- **WHEN** saved searches return exactly one valid default
|
||||
- **THEN** the opportunity payload uses `queries/<savedSearchNumber>` and reuses it throughout pagination
|
||||
|
||||
#### Scenario: No valid default
|
||||
- **WHEN** no unique default saved search is returned
|
||||
- **THEN** the extension reports the failure instead of using a hard-coded saved-search identifier
|
||||
|
||||
### Requirement: Opportunities display before background enrichment
|
||||
The extension SHALL collect the opportunity result pages before displaying the ready list, then start Service Request and product enrichment without waiting for them to finish. Responses from an obsolete Reference request SHALL not replace the active result.
|
||||
|
||||
#### Scenario: SR remains pending
|
||||
- **WHEN** opportunity pagination completes and Service Request loading remains pending
|
||||
- **THEN** the opportunity table is already usable
|
||||
|
||||
#### Scenario: Reference changes during loading
|
||||
- **WHEN** an older query completes after a newer Reference query has started
|
||||
- **THEN** the older result does not overwrite the active view
|
||||
|
||||
### Requirement: Reference uses Oracle fiscal periods
|
||||
The selected Reference SHALL determine the query date range using a June-through-May fiscal year. Opportunity type selections SHALL also constrain the query; an empty type selection SHALL show an explanatory empty state without sending an opportunity query.
|
||||
|
||||
#### Scenario: Fiscal first quarter
|
||||
- **WHEN** Reference resolves to the first fiscal quarter
|
||||
- **THEN** the selected period covers June through August with the next quarter boundary excluded
|
||||
|
||||
### Requirement: Filters are coordinated across views
|
||||
Overview and Calendar SHALL share search, Customer, Owner, Status, Stage, eligible SR/Action filters and Booking/Workload filters. Customer options SHALL narrow by selected Owners and Owner options by selected Customers without additional API calls.
|
||||
|
||||
#### Scenario: Customer narrows owner choices
|
||||
- **WHEN** a customer associated with two owners is selected
|
||||
- **THEN** the Owner choices contain the corresponding owners and widening the customer selection restores applicable choices
|
||||
|
||||
#### Scenario: All-selected item is clicked
|
||||
- **WHEN** the user clicks an item while all choices in its multiselect or filter-badge group are selected
|
||||
- **THEN** only that item remains selected and subsequent clicks can add other choices
|
||||
|
||||
#### Scenario: Booking isolation
|
||||
- **WHEN** both Booking and Workload are selected and Booking is clicked
|
||||
- **THEN** only Booking opportunities remain visible in both views
|
||||
|
||||
### Requirement: Overview preserves table meaning and ordering
|
||||
Overview SHALL restore its last sort column and direction, display customer `PartyName`, label win probability `Prob.`, and give Name and Customer greater width priority. Monetary cells and their headers SHALL align right; other headers SHALL align left.
|
||||
|
||||
#### Scenario: Overview reopens
|
||||
- **WHEN** the user reopens Overview after selecting a descending Amount sort
|
||||
- **THEN** that ordering is restored and the displayed amount values determine the order
|
||||
|
||||
### Requirement: Indicators reflect the filtered opportunities
|
||||
The opportunity count and stage amounts SHALL follow the active filters without issuing additional queries solely to calculate the displayed indicators.
|
||||
|
||||
#### Scenario: Local filter changes
|
||||
- **WHEN** the user narrows the loaded list using a Customer filter
|
||||
- **THEN** the count and stage indicators update with the filtered opportunities
|
||||
@@ -0,0 +1,66 @@
|
||||
## Purpose
|
||||
|
||||
Maintain customer organization charts locally while enriching people with Oracle contact information and related opportunities.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Charts are scoped and stored locally
|
||||
Charts SHALL persist JSON-compatible records in extension-owned IndexedDB, scoped by user and customer in the browser profile. Records SHALL include revision and update metadata; stale saves SHALL be rejected. Email SHALL not persist in chart nodes.
|
||||
|
||||
#### Scenario: Concurrent chart change
|
||||
- **WHEN** a user saves an outdated revision after another window has saved the chart
|
||||
- **THEN** the save is rejected with guidance to reopen the current chart
|
||||
|
||||
#### Scenario: Browser profile is different
|
||||
- **WHEN** the same user accesses the customer in another browser profile
|
||||
- **THEN** this local chart is not automatically synchronized to that profile
|
||||
|
||||
### Requirement: Hierarchy editing preserves remaining people
|
||||
The chart SHALL support adding people, changing their manager, notes, branch expansion/collapse, zoom and panning. It SHALL reject invalid hierarchies, support up to 500 people and 60 levels, and promote direct reports to the removed person's manager when a person is deleted.
|
||||
|
||||
#### Scenario: Manager is deleted
|
||||
- **WHEN** a user deletes a person with direct reports
|
||||
- **THEN** those reports remain in the chart under the deleted person's manager
|
||||
|
||||
#### Scenario: Unsaved chart is closed
|
||||
- **WHEN** the user closes a chart with unsaved changes
|
||||
- **THEN** the extension requests confirmation before discarding those changes
|
||||
|
||||
### Requirement: Contact autocomplete is debounced and customer-scoped
|
||||
Name autocomplete SHALL search contacts after a 350 ms typing pause, filter by the customer's PartyId, display PartyName and JobTitle, and ignore superseded results. Empty queries and opening the chart alone SHALL not issue contact searches.
|
||||
|
||||
#### Scenario: User keeps typing
|
||||
- **WHEN** another character arrives before the search delay expires
|
||||
- **THEN** the pending search is superseded rather than sending one query per character
|
||||
|
||||
### Requirement: Person details refresh contact data on demand
|
||||
Opening a stored person SHALL query contacts using the person's Name as keywords and match by contact PartyId. A matching result SHALL refresh Name and Job Title while preserving notes and reporting relationships; Email SHALL remain transient. Job Title SHALL be eligible for chart persistence.
|
||||
|
||||
#### Scenario: Contact data changed
|
||||
- **WHEN** a matching contact response has a new name or job title
|
||||
- **THEN** the working chart updates those fields and retains the person's notes and manager
|
||||
|
||||
### Requirement: Contact PartyNumber is preserved as an opaque identifier
|
||||
Chart nodes SHALL retain the contact's PartyNumber, including alphanumeric values. Opening person details SHALL persist a returned PartyNumber; opportunity lookup SHALL use an existing stored value and attempt resolution when it is missing.
|
||||
|
||||
#### Scenario: Alphanumeric number is already saved
|
||||
- **WHEN** opportunities are requested for a person with PartyNumber `A4KCS2P`
|
||||
- **THEN** that exact value is used in `OpportunityContact.ContactPartyNumber`, without numeric conversion
|
||||
|
||||
### Requirement: Contact opportunity tables load all pages
|
||||
The person card SHALL provide an opportunities action that opens `Opportunities | <name>`, shows a skeleton while loading and follows `hasMore` until all pages are collected. The resulting table SHALL be sortable and link each Name to its corresponding opportunity in a new tab.
|
||||
|
||||
#### Scenario: Contact has more than one result page
|
||||
- **WHEN** the opportunities response sets `hasMore=true`
|
||||
- **THEN** the next offset is queried using the same contact PartyNumber until the result is complete
|
||||
|
||||
### Requirement: New contacts are created explicitly
|
||||
The contact-creation form SHALL require First Name, Last Name and Email, map email/phone consent to their corresponding Do/DoNot flags and obtain account identifiers from the selected customer. Provided phone components SHALL be combined as country code, hyphen and number. Save SHALL submit directly without a payload-preview step.
|
||||
|
||||
#### Scenario: Optional phone is omitted
|
||||
- **WHEN** required contact fields are valid but a phone number is not filled
|
||||
- **THEN** that absent phone value is not included as a populated contact field
|
||||
|
||||
#### Scenario: Phone components are entered
|
||||
- **WHEN** country code `55` and phone number `99999999999` are provided
|
||||
- **THEN** the submitted raw phone value is `55-99999999999`
|
||||
@@ -0,0 +1,44 @@
|
||||
## Purpose
|
||||
|
||||
Preserve user preferences and reuse eligible data without allowing expired or invalidated results to silently replace fresh information.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Preferences survive reopening
|
||||
The extension SHALL persist supported filter preferences, theme, opportunity type selections and cache duration in the browser profile. Invalid or unavailable stored values SHALL fall back to usable defaults or in-memory state.
|
||||
|
||||
#### Scenario: Stored preference cannot be read
|
||||
- **WHEN** browser storage is unavailable or a saved preference is invalid
|
||||
- **THEN** the extension remains usable with its fallback rather than failing to open
|
||||
|
||||
### Requirement: Sort preferences belong to individual tables
|
||||
Supported sortable tables SHALL retain their own last sort key and direction without changing other tables' preferences. Product detail tables SHALL remain excluded from this sorting behavior.
|
||||
|
||||
#### Scenario: Two tables use different sorts
|
||||
- **WHEN** the user sorts Installed Base by amount and contact opportunities by close date
|
||||
- **THEN** reopening each table restores its own saved ordering
|
||||
|
||||
### Requirement: Cache reuse respects validity and identity boundaries
|
||||
Product, workload and activity caches SHALL apply their configured lifetimes and existing identity/account/product-update scopes. A missing or expired activity cache SHALL not be represented as a confirmed empty result.
|
||||
|
||||
#### Scenario: Workload token rotates
|
||||
- **WHEN** the same user's account workload data is still valid but the authorization token changes
|
||||
- **THEN** the account data can be reused without treating the token string as a different customer identity
|
||||
|
||||
### Requirement: Only eligible reads are reused
|
||||
Form request caching SHALL reuse only known read operations, share concurrent reads and invalidate applicable entries after successful writes. Create, update and delete operations SHALL not be served from a response cache.
|
||||
|
||||
#### Scenario: Repeated write
|
||||
- **WHEN** the user explicitly submits a new valid write operation
|
||||
- **THEN** the operation goes through the write transport rather than returning a cached success
|
||||
|
||||
### Requirement: Refresh all invalidates reusable data safely
|
||||
Refresh all SHALL invalidate product/activity and related cached data before reloading the active Reference, preserve user preferences and authentication, and prevent pre-invalidation responses from repopulating invalidated cache entries. Cache invalidation errors SHALL be reported.
|
||||
|
||||
#### Scenario: Old product request finishes after refresh
|
||||
- **WHEN** an old request completes after its cache has been invalidated
|
||||
- **THEN** its result does not restore the invalidated cache snapshot
|
||||
|
||||
#### Scenario: Activity updates arrive
|
||||
- **WHEN** only background activity lookup results change
|
||||
- **THEN** those lookups do not independently advance the product Last update timestamp
|
||||
@@ -0,0 +1,55 @@
|
||||
## Purpose
|
||||
|
||||
Enrich opportunities with products and workload information and support review and explicit updates of consumption projections.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Product enrichment runs in the background
|
||||
Product loading SHALL update opportunity product counts and progress without blocking the displayed opportunity list. Product detail tables SHALL retain their source order rather than applying the general table sorting preference.
|
||||
|
||||
#### Scenario: Some products are still loading
|
||||
- **WHEN** opportunities are visible and their products have not all arrived
|
||||
- **THEN** completed product results update their related opportunities while remaining products continue loading
|
||||
|
||||
### Requirement: Workload retrieval is shared by customer
|
||||
Workload retrieval SHALL consolidate all result pages for each distinct customer account, reuse eligible cached results and correlate workloads to products by revenue identifier. Concurrent consumers of the same account SHALL share loading.
|
||||
|
||||
#### Scenario: Multiple opportunities share a customer
|
||||
- **WHEN** their products require workloads for the same account
|
||||
- **THEN** one shared account retrieval supplies the matching products and continues while the response indicates more pages
|
||||
|
||||
### Requirement: Booking classification requires loaded products without Workload names
|
||||
An opportunity with a nonempty loaded product list SHALL display a distinct Booking badge when every product has a blank or `-` Workload name. If any product has a Workload name, the existing ramp badge behavior SHALL remain.
|
||||
|
||||
#### Scenario: No products have an assigned Workload
|
||||
- **WHEN** all loaded products have blank or `-` Workload names
|
||||
- **THEN** Booking replaces Ramp Months and the opportunity matches the Booking filter
|
||||
|
||||
#### Scenario: Mixed product assignments
|
||||
- **WHEN** at least one product has a Workload name
|
||||
- **THEN** the opportunity retains its ramp behavior and is not classified as Booking
|
||||
|
||||
### Requirement: Projection access is independent of a difference alert
|
||||
Clicking a ramp badge SHALL open consumption projection even when forecast and calculated amounts match. Difference alerts SHALL be placed between ramp and SR badges; product alerts without a workload record SHALL indicate unavailability with disabled styling.
|
||||
|
||||
#### Scenario: Forecast matches calculation
|
||||
- **WHEN** the user clicks a ramp badge for a product with no forecast difference
|
||||
- **THEN** Consumption projection still opens
|
||||
|
||||
### Requirement: Projection comparison uses calculated monthly values
|
||||
Consumption projection SHALL calculate monthly amounts using adjusted ACR, ramp months and first-month proration, and compare forecast minus calculated amounts at cent precision.
|
||||
|
||||
#### Scenario: Monthly discrepancy
|
||||
- **WHEN** a calculated monthly amount differs from its forecast after rounding to cents
|
||||
- **THEN** the comparison shows the difference and enables the corresponding alert
|
||||
|
||||
### Requirement: Estimate updates require confirmation
|
||||
Update estimates SHALL ask for confirmation before writing calculated values to SPA, prevent duplicate submissions and report success or failure. Successful updates SHALL refresh the comparison and invalidate affected workload cache data.
|
||||
|
||||
#### Scenario: Confirmation is cancelled
|
||||
- **WHEN** the user declines the update confirmation
|
||||
- **THEN** no forecast update is sent
|
||||
|
||||
#### Scenario: Confirmed update succeeds
|
||||
- **WHEN** the user confirms and the update request succeeds
|
||||
- **THEN** the comparison reflects the new values and subsequent workload reads do not reuse the invalidated values
|
||||
@@ -0,0 +1,51 @@
|
||||
## Purpose
|
||||
|
||||
Make extension HTTP activity inspectable without pre-rendering an ever-growing request interface or confusing cached data with new network operations.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: HTTP activity has a visible lifecycle
|
||||
Debug Requests SHALL record request identity, method, URL, timing, headers, body, response and final status when available. Running requests SHALL transition to success or failure, cache hits SHALL not create fictitious HTTP requests, and entries SHALL be grouped by request category.
|
||||
|
||||
#### Scenario: Request is pending
|
||||
- **WHEN** a logged request has started but not completed
|
||||
- **THEN** it is displayed as running with its start time and later updates with completion or failure
|
||||
|
||||
### Requirement: Request history is persisted per tab context
|
||||
Request records SHALL be stored in page localStorage under a tab-specific namespace. Closing the main modal SHALL preserve them. Starting page one of a new opportunity query SHALL reset that history; later pages of the same query SHALL retain it.
|
||||
|
||||
#### Scenario: Modal closes and reopens
|
||||
- **WHEN** the main modal closes and reopens without a new opportunity query
|
||||
- **THEN** the existing debug history remains available
|
||||
|
||||
#### Scenario: New query begins
|
||||
- **WHEN** the first opportunity page is about to be sent
|
||||
- **THEN** old history is cleared for that tab without deleting preferences or another tab's debug records
|
||||
|
||||
### Requirement: Debug rendering is deferred
|
||||
The hidden debug view SHALL avoid constructing request-detail DOM. Opening the view SHALL render request summaries and expanding a request SHALL construct its details, preserving expansion and scroll state across updates where applicable.
|
||||
|
||||
#### Scenario: Requests accumulate while debug is closed
|
||||
- **WHEN** requests complete while the debug panel is hidden
|
||||
- **THEN** records are captured without mounting their detail elements in the hidden panel
|
||||
|
||||
### Requirement: Debug access stays above other extension views
|
||||
Ctrl+Shift+D SHALL toggle Debug Requests as a full-page extension view above other extension modals. Closing it SHALL return to the underlying view without opening a browser tab or native fullscreen mode.
|
||||
|
||||
#### Scenario: Debug opens over person details
|
||||
- **WHEN** the user presses Ctrl+Shift+D while a nested modal is open
|
||||
- **THEN** Debug Requests appears in front of that modal
|
||||
|
||||
### Requirement: Sensitive-value masking is a display control
|
||||
Debug SHALL hide sensitive values by default and support explicit reveal of retained originals. Documentation SHALL distinguish masking from storage protection: captured debug records can retain sensitive response values and masking SHALL not be described as encryption or guaranteed redaction at rest.
|
||||
|
||||
#### Scenario: Identity token is captured
|
||||
- **WHEN** the identity response includes a token
|
||||
- **THEN** normal debug display hides the token and the explicit visibility control can reveal its retained value
|
||||
|
||||
### Requirement: Debug failures do not interrupt application requests
|
||||
Unavailable or full localStorage SHALL leave records available in memory with explanatory feedback. Debug timers and persistence errors SHALL not prevent the underlying network request from starting or completing.
|
||||
|
||||
#### Scenario: Storage quota is exhausted
|
||||
- **WHEN** persisting a request record fails due to localStorage quota
|
||||
- **THEN** the request outcome remains available in memory and the application request continues normally
|
||||
@@ -0,0 +1,55 @@
|
||||
## Purpose
|
||||
|
||||
Expose service requests linked to opportunities and customers, with progressive status badges, detail views and explicit record creation.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: CRM SR queries resolve their saved search
|
||||
Before the first CRM Service Request page, the extension SHALL retrieve SR search resources using the general Token Relay Bearer and use the first item's valid `savedSearchNumber` as `queries/<savedSearchNumber>` in `copiedFrom`.
|
||||
|
||||
#### Scenario: Search resources have no identifier
|
||||
- **WHEN** the first item has no valid saved-search number
|
||||
- **THEN** the dependent CRM SR query fails explicitly instead of using a fixed fallback
|
||||
|
||||
### Requirement: SR enrichment is progressive and nonblocking
|
||||
For eligible users, CRM SR pages SHALL load after opportunities are displayed and update their linked badges in the background. The query SHALL select pending-delivery team SRs and match opportunities through the returned opportunity number.
|
||||
|
||||
#### Scenario: First SR page arrives
|
||||
- **WHEN** more SR pages remain after the first successful page
|
||||
- **THEN** information received so far can update the visible opportunities without waiting for all pages
|
||||
|
||||
### Requirement: Failed SR loading remains distinguishable from no matches
|
||||
The extension SHALL distinguish loading, failed and confirmed empty SR results. Pagination SHALL detect lack of progress, retry each failed page at most five total attempts, and stop work superseded by a newer query.
|
||||
|
||||
#### Scenario: SR lookup fails
|
||||
- **WHEN** a lookup cannot establish whether an opportunity has matching SRs
|
||||
- **THEN** its badge indicates an unknown or failed state rather than confirmed absence
|
||||
|
||||
#### Scenario: Successful SR snapshot is reused
|
||||
- **WHEN** a subsequent cycle can reuse the completed SR result within the current page session
|
||||
- **THEN** it does not repeat the completed query unless explicitly invalidated
|
||||
|
||||
### Requirement: Customer SR details use the resolved account identifier
|
||||
Customer Service Requests SHALL resolve account summary first, use its `id` for the customer SR query and consolidate pages of open SRs. The dialog SHALL provide a loading skeleton, searchable sortable results, and guards against late results after closure.
|
||||
|
||||
#### Scenario: Account has distinct identifiers
|
||||
- **WHEN** account summary returns different `id` and `registryId` values
|
||||
- **THEN** customer SR retrieval uses `id`, not `registryId`
|
||||
|
||||
### Requirement: Internal SR recovery is bounded
|
||||
Internal SR details SHALL report failed requests and use bounded, shared session recovery rather than continuously issuing requests or opening a visible recovery tab.
|
||||
|
||||
#### Scenario: Endpoint remains unavailable
|
||||
- **WHEN** an Internal SR read continues to fail after its allowed recovery attempts
|
||||
- **THEN** the view shows failure and does not keep sending an unbounded automatic request loop
|
||||
|
||||
### Requirement: SR creation validates before writing
|
||||
Service Request creation SHALL require valid form inputs before submission, retain entered data on failure and prevent duplicate submissions while saving. Internal SR creation SHALL resolve parent SR and current resource information before linking the new record to its parent.
|
||||
|
||||
#### Scenario: Required fields are missing
|
||||
- **WHEN** Save is clicked on an incomplete SR form
|
||||
- **THEN** the missing fields are highlighted and no create request is sent
|
||||
|
||||
#### Scenario: Create request fails
|
||||
- **WHEN** a submitted SR creation fails
|
||||
- **THEN** the user receives error feedback and their form values remain available
|
||||
@@ -0,0 +1,54 @@
|
||||
## Purpose
|
||||
|
||||
Establish authenticated Oracle access before dependent data operations while preserving credential boundaries and profile restrictions.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Valid identity precedes dependent data requests
|
||||
The extension SHALL obtain a successful current-user response containing a valid user identifier, name, roles array and token before starting dependent opportunity or activity data requests. Concurrent identity consumers SHALL share acquisition, and invalid responses SHALL retry with backoff.
|
||||
|
||||
#### Scenario: HTML is returned with HTTP 200
|
||||
- **WHEN** current-user acquisition receives a login document instead of the required JSON
|
||||
- **THEN** dependent data requests remain blocked and identity acquisition retries
|
||||
|
||||
#### Scenario: Identity is already established
|
||||
- **WHEN** the user changes Reference or reopens the main modal in the same page session
|
||||
- **THEN** the extension reuses the successful identity without another current-user HTTP request
|
||||
|
||||
### Requirement: SPA recovery verifies the loaded session page
|
||||
SPA session recovery SHALL open the configured bootstrap URL in an inactive auxiliary tab and verify page readiness before probing identity. Login forms, error documents and OAuth callbacks SHALL not count as a ready SPA page.
|
||||
|
||||
#### Scenario: Recovery navigation
|
||||
- **WHEN** identity recovery requires a SPA session
|
||||
- **THEN** navigation starts at `https://spa.oracle.com/oalcrm/web/api/g2m-consumer-application/ui/index.html?ojr=whitespace`
|
||||
- **AND** the extension preserves the originating browser context and closes its owned auxiliary tab when recovery finishes
|
||||
|
||||
#### Scenario: Rejected callback document
|
||||
- **WHEN** recovery encounters an authorization-error callback
|
||||
- **THEN** it restarts from the configured bootstrap URL instead of replaying that callback as a successful session
|
||||
|
||||
### Requirement: SR session preparation has independent progress
|
||||
SR session preparation SHALL be able to run concurrently with SPA identity preparation, using the SeaaS external application URL. It SHALL expose completion or failure and allow a user retry after failure.
|
||||
|
||||
#### Scenario: SR preparation fails
|
||||
- **WHEN** preparation through `https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/SeaaS_initiation/live/webApps/external/` fails or reaches its 70-second timeout
|
||||
- **THEN** the extension offers retry rather than declaring the SR session ready
|
||||
|
||||
### Requirement: SALES_REP activity access is restricted
|
||||
For a user whose roles include `SALES_REP`, the extension SHALL hide CRM SR and Workload Action badges and Manage Time access, and SHALL not issue their dependent activity or Manage Time data requests.
|
||||
|
||||
#### Scenario: Restricted user after successful authentication
|
||||
- **WHEN** identity resolves with the `SALES_REP` role
|
||||
- **THEN** opportunities remain available but CRM activity badges and Manage Time are unavailable
|
||||
- **AND** attempting to open Manage Time does not load its data
|
||||
|
||||
### Requirement: Credentials are specific to each Oracle service
|
||||
The extension SHALL preserve operation-specific credentials and cookie inclusion. It SHALL use the general Token Relay Bearer for Fusion queries and the appropriate SPA consumer authorization for each SPA service rather than substituting token families.
|
||||
|
||||
#### Scenario: Customer SR authorization
|
||||
- **WHEN** customer service requests are loaded using SPA-ORANGE authorization
|
||||
- **THEN** the raw authorization value is sent in `custsr-auth` without a Bearer prefix
|
||||
|
||||
#### Scenario: Token Relay does not finish
|
||||
- **WHEN** a Token Relay request exceeds its request timeout
|
||||
- **THEN** the attempt reports failure instead of remaining indefinitely pending in Debug Requests
|
||||
@@ -0,0 +1,40 @@
|
||||
## Purpose
|
||||
|
||||
Identify workload actions owned by the signed-in user and allow eligible users to create actions for opportunity products.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Action enrichment respects prerequisite data
|
||||
Workload Action enrichment SHALL use distinct product revenue identifiers after the product cycle and successful or reused CRM SR loading. Unavailable SR data SHALL leave action state unknown rather than treating it as an empty result.
|
||||
|
||||
#### Scenario: SR prerequisite fails
|
||||
- **WHEN** CRM SR loading fails for a completed product cycle
|
||||
- **THEN** action enrichment is blocked and its badges do not assert that no actions exist
|
||||
|
||||
### Requirement: Ownership determines the action badge
|
||||
The action badge SHALL aggregate returned actions for the opportunity products and mark a match when an action owner equals the general Token Relay principal. Missing principal or failed lookups SHALL not count as confirmed nonmatches.
|
||||
|
||||
#### Scenario: Actions exist for other owners
|
||||
- **WHEN** returned actions have no owner matching the known principal
|
||||
- **THEN** the badge indicates no matching ownership while its tooltip retains the returned actions
|
||||
|
||||
### Requirement: Read attempts are bounded and partial coverage is disclosed
|
||||
Each action lookup SHALL make at most five total attempts and stop on success or session supersession. The current lookup SHALL expose `hasNext` as additional unqueried actions rather than implying that all pages were loaded.
|
||||
|
||||
#### Scenario: More action pages exist
|
||||
- **WHEN** a successful action response sets `hasNext=true`
|
||||
- **THEN** the tooltip states that additional actions exist and pagination is not enabled
|
||||
|
||||
### Requirement: Action forms use validated lookup selections
|
||||
The Action form SHALL load team members and lookup values with the workload credential, support searchable selections, and submit selected codes rather than arbitrary typed search text. Required inputs and the date range SHALL be validated before Save.
|
||||
|
||||
#### Scenario: Search text is not an option
|
||||
- **WHEN** the user types a value without selecting a valid lookup result
|
||||
- **THEN** the text is not submitted as a valid option value
|
||||
|
||||
### Requirement: Action creation is explicit and preserves failure state
|
||||
Saving a valid action SHALL send current-user attribution, UTC dates and a notes array, lock duplicate submission while pending and show a result toast. A failed create SHALL retain the form without automatically retrying the POST.
|
||||
|
||||
#### Scenario: Create fails
|
||||
- **WHEN** the server rejects an action creation
|
||||
- **THEN** the form remains available with the entered data and no automatic duplicate POST is issued
|
||||
@@ -0,0 +1,34 @@
|
||||
# Tasks
|
||||
|
||||
These are application-phase tasks for a documentation baseline. Creating these planning artifacts does not complete the documentation edits below. No task authorizes runtime feature changes, schema customization, a release, or live Oracle writes.
|
||||
|
||||
## 1. Reconcile the documented user experience
|
||||
|
||||
- [x] 1.1 Update README.md Opportunity Views to describe the current Calendar, coordinated Customer/Owner filters, filter isolation and persisted sorting; verify against `tests/opportunityCalendar.test.cjs`, `tests/dependentFilters.test.cjs`, `tests/allOpportunityFilters.test.cjs` and `tests/tableSorting.test.cjs` with the existing Node test runner.
|
||||
- [x] 1.2 Update README.md product/workload, Booking and projection descriptions and remove active AI-summary descriptions; verify the relevant behavior against `tests/badgeIcons.test.cjs`, `tests/ramp-projection.test.cjs` and `tests/workload-forecast-update.test.cjs`, and confirm no active AI API/module claim remains in README.md.
|
||||
- [x] 1.3 Update README.md Organization Charts with stored alphanumeric PartyNumber, transient email, on-demand contact refresh, creation and paginated contact opportunities; verify against `tests/orgChart.test.cjs` and `tests/accountContact.test.cjs` without sending real contact writes.
|
||||
- [x] 1.4 Update README.md customer insights and shell coverage with Rate Card order filtering, printing, favorite shortcuts/hints and draggable modal headers; verify against the relevant source and `tests/ratecard.test.cjs`, `tests/bookmarkShortcut.test.cjs`, `tests/bookmarkHint.test.cjs` and `tests/dialogDrag.test.cjs`, recording any visual behavior that remains untested in an installed browser.
|
||||
|
||||
## 2. Reconcile authentication and asynchronous loading
|
||||
|
||||
- [x] 2.1 Update README.md authentication to use the current SPA bootstrap URL, identity reuse, independent SR session preparation and SALES_REP restrictions including Manage Time; verify against `tests/currentUser.test.cjs`, `tests/srSessionPreparation.test.cjs` and `tests/manageTime.test.cjs`.
|
||||
- [x] 2.2 Correct README.md SR/Actions sequencing and saved-search contracts, including progressive SR badges and allowed activity cache-miss requests for cached products; verify against `tests/srRequestPriority.test.cjs`, `tests/crmServiceRequests.test.cjs`, `tests/activityProgress.test.cjs` and `tests/productActivities.test.cjs`.
|
||||
- [x] 2.3 Revise docs/architecture.md runtime contexts, generated manifest permissions/hosts, service credentials, saved searches and timeout/stale-response behavior; verify each changed contract against `scripts/build.mjs`, composition roots and relevant service/auth sources, and run `tests/architecture.test.cjs` and `tests/buildOutput.test.cjs`.
|
||||
|
||||
## 3. Reconcile persistence and establish documentation navigation
|
||||
|
||||
- [x] 3.1 Update docs/architecture.md storage ownership and cache lifetimes for preferences, debug, identity/session state, products, workloads, activities and organization charts; verify each storage location/key against source and `tests/activityCache.test.cjs`, `tests/formRequestCache.test.cjs`, `tests/workloads.test.cjs` and `tests/refreshAll.test.cjs`.
|
||||
- [x] 3.2 Correct README.md and docs/architecture.md debug descriptions to include lazy rendering, page-one reset, persistence across modal closure and the distinction between masking and stored originals; verify against `tests/debugStorage.test.cjs` and `tests/debugTabs.test.cjs` and remove blanket claims that all credentials remain only in memory.
|
||||
- [x] 3.3 Add concise OpenSpec navigation to README.md and link the architecture documentation to the capability baseline, clearly identifying this change as proposed until archival; verify link targets, retain `# Opportunities Extension`, keep historical notes in RELEASE_NOTES.md and confirm no schema/config change is included.
|
||||
|
||||
## 4. Validate the integrated baseline
|
||||
|
||||
- [x] 4.1 Review all twelve capability specifications against the final documented behavior and evidence map; verify every requirement has a WHEN/THEN scenario, every proposed capability has one matching spec file, and no runtime enhancement is concealed as an existing contract. Record unresolved discrepancies rather than silently changing code.
|
||||
- [x] 4.2 Run `openspec validate document-project-baseline --strict` and `node scripts/build.mjs --check`; verify strict validation succeeds and generated browser packages are unchanged and current.
|
||||
- [x] 4.3 Run `node scripts/test.cjs` for final integration verification and `git diff --check`; record results and explicitly distinguish synthetic coverage from any unperformed installed-browser or live Oracle checks. Confirm the final change is confined to approved documentation and OpenSpec artifacts, with version and release notes unchanged.
|
||||
|
||||
## Workflow follow-up
|
||||
|
||||
- After application and review, use `$openspec-archive-change document-project-baseline` to promote the baseline specifications and archive the change. Archival is not a prerequisite for completing the tracked tasks.
|
||||
- Confirm `openspec list --specs --json` lists the twelve promoted capabilities, no generated Purpose placeholder remains, and README navigation resolves to the durable specs.
|
||||
- Use capability-specific delta changes for future behavior updates; do not rewrite the baseline from release history or silently replace it with an unreviewed implementation snapshot.
|
||||
32
openspec/config.yaml
Normal file
32
openspec/config.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
schema: spec-driven
|
||||
|
||||
# Project context (optional)
|
||||
# Add only constraints that should guide OpenSpec artifacts and workflows.
|
||||
# Include constraints an agent cannot infer by reading the code.
|
||||
# Keep general project documentation and discoverable codebase facts out.
|
||||
# Example:
|
||||
# context: |
|
||||
# Designs and tasks must cover Windows, macOS, and Linux
|
||||
# Write all artifacts in Spanish
|
||||
|
||||
# Per-artifact rules (optional)
|
||||
# Add custom rules for specific artifacts.
|
||||
# Example:
|
||||
# rules:
|
||||
# proposal:
|
||||
# - Keep proposals under 500 words
|
||||
# - Always state what is out of scope
|
||||
# tasks:
|
||||
# - Break tasks into chunks of max 2 hours
|
||||
|
||||
# Per-operation guidance (optional)
|
||||
# Add advisory guidance for how apply and archive work should be conducted.
|
||||
# This is separate from artifact rules above.
|
||||
# Example:
|
||||
# operations:
|
||||
# apply:
|
||||
# guidance:
|
||||
# - Keep test summaries concise
|
||||
# archive:
|
||||
# guidance:
|
||||
# - Summarize the archive outcome before finishing
|
||||
0
openspec/specs/.gitkeep
Normal file
0
openspec/specs/.gitkeep
Normal file
53
openspec/specs/customer-insights/spec.md
Normal file
53
openspec/specs/customer-insights/spec.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# customer-insights Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
Provide customer-specific Installed Base and consumption exploration without disrupting the main opportunity view.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Installed Base uses the registry identifier
|
||||
Installed Base SHALL first resolve account summary and query using its `registryId` with the SAIB authorization. It SHALL continue pagination until `hasMore=false`, and reject invalid or stalled pages instead of presenting a partial list as complete.
|
||||
|
||||
#### Scenario: More installed items exist
|
||||
- **WHEN** an Installed Base page returns `hasMore=true`
|
||||
- **THEN** subsequent pages are loaded before the complete result is presented
|
||||
|
||||
### Requirement: Installed Base avoids duplicate customer presentation
|
||||
Installed Base SHALL show the customer in the modal header, omit the Customer column, and provide searchable sortable data with loading skeletons.
|
||||
|
||||
#### Scenario: User searches installed items
|
||||
- **WHEN** search text is entered
|
||||
- **THEN** loaded rows and the result count update locally without another account query
|
||||
|
||||
### Requirement: Consumption follows the selected plan
|
||||
Customer consumption SHALL resolve available account plans and load trends for the selected plan with quarterly, monthly, weekly and daily periods. Plan detail loading SHALL be independent of trend loading and failed details SHALL not block the chart.
|
||||
|
||||
#### Scenario: User switches plans
|
||||
- **WHEN** the selected plan changes while an earlier plan request is pending
|
||||
- **THEN** late results from the earlier plan do not replace the selected plan's view
|
||||
|
||||
### Requirement: Projection details preserve safe order navigation
|
||||
Consumption plan details SHALL expose Forfeit and Overage information with nested line details in interactive tooltips. Only HTTPS order links on `accountdashboard.oracle.com` SHALL be clickable.
|
||||
|
||||
#### Scenario: Unsafe order URL
|
||||
- **WHEN** a returned order URL uses a different host or unsupported scheme
|
||||
- **THEN** the detail remains readable without offering that URL as a clickable order link
|
||||
|
||||
### Requirement: Rate Card queries the active plan
|
||||
Rate Card SHALL query using the selected plan's `subPlanNum` and OCICONS authorization, show plan/customer context and provide search, sorting and multi-selection of distinct Order Numbers. The current request SHALL use a 10000-record limit without implying unsupported cursor pagination.
|
||||
|
||||
#### Scenario: Order filter isolates one choice
|
||||
- **WHEN** all order numbers are selected and the user clicks one order
|
||||
- **THEN** only that order remains selected and search continues to combine with the order filter
|
||||
|
||||
#### Scenario: Rate Card closes while loading
|
||||
- **WHEN** the drawer closes before its request completes
|
||||
- **THEN** the late result does not reopen or overwrite a different active plan view
|
||||
|
||||
### Requirement: Customer tables sort and search by meaningful values
|
||||
Customer table search SHALL match case-insensitively and accent-insensitively across displayed values. Sorting SHALL use numeric or date values where applicable, and restore each supported table's saved ordering.
|
||||
|
||||
#### Scenario: Numeric amount ordering
|
||||
- **WHEN** the user sorts a customer table by a monetary column
|
||||
- **THEN** rows are ordered by numeric amount rather than by the formatted text
|
||||
49
openspec/specs/extension-shell/spec.md
Normal file
49
openspec/specs/extension-shell/spec.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# extension-shell Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
Provide predictable entry points, navigation, modal interaction and printing across the supported browser extension targets.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Supported Fusion pages expose the extension
|
||||
The extension SHALL provide its entry tile on the configured Oracle Fusion hcmUI and fscmUI FuseWelcome pages. A bookmarked URL with the extension shortcut marker SHALL open the main modal without requiring a click on the Sales group.
|
||||
|
||||
#### Scenario: Fusion rewrites the URL
|
||||
- **WHEN** the user follows the shortcut URL and Fusion subsequently replaces its query string
|
||||
- **THEN** the captured shortcut intent still permits the extension to open once when ready
|
||||
|
||||
### Requirement: Favorites use an explicit folder choice
|
||||
Ctrl+Shift+F within the extension SHALL open a searchable browser-bookmark folder picker. Saving SHALL use the chosen writable folder and extension shortcut URL rather than silently choosing an arbitrary location.
|
||||
|
||||
#### Scenario: User selects a bookmark folder
|
||||
- **WHEN** the user confirms a writable folder and saves
|
||||
- **THEN** the extension shortcut is saved in that folder
|
||||
|
||||
### Requirement: Bookmark discovery keeps Last update first
|
||||
When the shortcut is not bookmarked, the header SHALL show a prominent shortcut hint for 20 seconds. Last update SHALL remain the first badge and other badges SHALL appear to its right.
|
||||
|
||||
#### Scenario: Favorite is saved while the hint is visible
|
||||
- **WHEN** the shortcut is successfully added to bookmarks
|
||||
- **THEN** the favorite hint is removed without waiting for the remaining timeout
|
||||
|
||||
### Requirement: Non-full-page modals can be dragged by their header
|
||||
Non-full-page modals SHALL support dragging from noninteractive areas of their title bar, allowing up to 70 percent of their width and height beyond viewport edges. Header controls SHALL retain their own interactions and full-page views SHALL not become draggable.
|
||||
|
||||
#### Scenario: Drag exceeds viewport edge
|
||||
- **WHEN** the user drags a movable modal far outside the viewport
|
||||
- **THEN** movement is clamped so at least 30 percent of each modal dimension remains within the allowed bounds
|
||||
|
||||
### Requirement: Shared presentation remains consistent
|
||||
Modal titles, spacing, loading skeletons and table presentation SHALL follow the extension's shared visual patterns in light and dark themes. User-facing labels SHALL use English, with service-provided names preserved.
|
||||
|
||||
#### Scenario: Customer detail is opened while loading
|
||||
- **WHEN** the user opens a customer table before its data arrives
|
||||
- **THEN** its title and loading skeleton use the shared modal styling
|
||||
|
||||
### Requirement: Print output reflects the current opportunity view
|
||||
The print action beside Booking/Workload filters SHALL produce a landscape-oriented browser print layout containing active filter summaries, indicators and the opportunity list with page padding.
|
||||
|
||||
#### Scenario: All customers and owners are selected
|
||||
- **WHEN** the user opens the print layout with unrestricted Customer and Owner selections
|
||||
- **THEN** it labels them `All customers` and `All owners` instead of expanding every selected name
|
||||
53
openspec/specs/manage-time/spec.md
Normal file
53
openspec/specs/manage-time/spec.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# manage-time Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
Let authorized users review and maintain weekly time entries with validated hours and explicit, traceable persistence.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Manage Time requires profile and session readiness
|
||||
Manage Time SHALL remain unavailable to `SALES_REP` users. For eligible users, its launcher SHALL remain disabled until SR session readiness, and data request entry points SHALL enforce the profile gate before loading time data.
|
||||
|
||||
#### Scenario: Restricted profile with a ready session
|
||||
- **WHEN** SR session preparation succeeds for a user with `SALES_REP`
|
||||
- **THEN** Manage Time remains hidden and opening it does not send its data requests
|
||||
|
||||
### Requirement: Week navigation preserves the user's work
|
||||
Manage Time SHALL restore its selected reference date, navigate in seven-day increments and retain local drafts while moving between weeks within the modal. Late responses for a different week or closed modal SHALL not replace active values.
|
||||
|
||||
#### Scenario: Navigate away and back
|
||||
- **WHEN** the user edits an unsaved week, navigates to another week and returns
|
||||
- **THEN** the earlier week's local edits remain available
|
||||
|
||||
### Requirement: Entry selections are dependent and searchable
|
||||
Service Request, Activity and Task Type selections SHALL support autocomplete. Activities SHALL correspond to the chosen SR, task types SHALL match Service or Non Service rows, and duplicate SR selection SHALL be rejected with row feedback.
|
||||
|
||||
#### Scenario: Duplicate SR
|
||||
- **WHEN** a user selects an SR already used by another row
|
||||
- **THEN** the previous selection is restored and the existing row is highlighted
|
||||
|
||||
### Requirement: Hours are validated before persistence
|
||||
Each entered daily hour value SHALL be numeric and within the inclusive range 0 through 24. The view SHALL show daily totals and reject invalid rows before any affected write.
|
||||
|
||||
#### Scenario: Invalid daily hours
|
||||
- **WHEN** a user attempts to save a row containing 25 hours for one day
|
||||
- **THEN** validation prevents that invalid time entry from being submitted
|
||||
|
||||
### Requirement: Save controls creation updates and deletions
|
||||
Save SHALL create new entries with POST, update changed persisted entries with PUT and apply queued persisted deletions with DELETE. Removing an unsaved row SHALL remain local. Writes SHALL use the required session and current-resource context.
|
||||
|
||||
#### Scenario: Persisted row is removed before Save
|
||||
- **WHEN** a user removes a persisted row without saving
|
||||
- **THEN** the deletion remains queued and no DELETE is sent yet
|
||||
|
||||
#### Scenario: Partial save failure
|
||||
- **WHEN** some entry operations succeed and another operation fails
|
||||
- **THEN** successful results remain reflected locally and unfinished work remains available for retry without duplicating confirmed writes
|
||||
|
||||
### Requirement: Loading and failures are local to the time view
|
||||
Manage Time SHALL display skeleton rows while loading and provide retry on data failure without discarding the user's current draft values.
|
||||
|
||||
#### Scenario: Week retrieval fails
|
||||
- **WHEN** the active week's request fails
|
||||
- **THEN** the modal exposes the failure and retry while protecting existing edits
|
||||
46
openspec/specs/opportunity-calendar/spec.md
Normal file
46
openspec/specs/opportunity-calendar/spec.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# opportunity-calendar Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
Present the filtered opportunities by close date in a vertically navigable calendar bounded by the chosen Reference.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Calendar is a Reference-bounded monthly view
|
||||
Calendar SHALL show a continuous monthly view restricted to the selected Reference, with vertical scrolling and no month/week switch or previous/next navigation buttons. Switching between Overview and Calendar SHALL not fetch opportunities again.
|
||||
|
||||
#### Scenario: Reference spans multiple months
|
||||
- **WHEN** the user opens Calendar for a multi-month Reference
|
||||
- **THEN** all months in the Reference remain reachable by vertical scrolling, including months with no opportunities
|
||||
|
||||
### Requirement: Every daily opportunity has a card
|
||||
Each day SHALL show cards for all matching opportunities with a scrollable daily region when necessary. A hidden-event overflow link SHALL not replace the extra cards.
|
||||
|
||||
#### Scenario: Many opportunities close on one day
|
||||
- **WHEN** the day's cards exceed its available height
|
||||
- **THEN** the user can scroll within the day to reach all cards and the count reflects all matching opportunities
|
||||
|
||||
### Requirement: Initial positioning includes adjacent weeks
|
||||
When today is within Reference, Calendar SHALL position around the current week and adjust visible week sizing to include the preceding and following weeks where the Reference permits. Dates outside Reference SHALL remain excluded.
|
||||
|
||||
#### Scenario: Current week crosses a month boundary
|
||||
- **WHEN** Calendar positions around today and the three-week interval crosses into another month
|
||||
- **THEN** the rendered portions of those weeks are included in the positioning calculation
|
||||
|
||||
### Requirement: Dates retain their calendar-day meaning
|
||||
Calendar SHALL use `EffectiveDate` as a date-only close date without timezone shifts. Opportunities with missing or invalid close dates SHALL remain available in a separate list, and fiscal week labels SHALL use Sunday-start weeks and a June-start fiscal year.
|
||||
|
||||
#### Scenario: API date includes an offset
|
||||
- **WHEN** an opportunity close date contains a timezone offset
|
||||
- **THEN** its card retains the API calendar day instead of shifting to an adjacent day
|
||||
|
||||
#### Scenario: Missing close date
|
||||
- **WHEN** a filtered opportunity has no valid close date
|
||||
- **THEN** it is accessible through the undated-opportunities list
|
||||
|
||||
### Requirement: Calendar details are read-only
|
||||
Opportunity cards SHALL show stage information and open read-only details with the corresponding opportunity link. Calendar labels and controls SHALL be in English.
|
||||
|
||||
#### Scenario: User selects a card
|
||||
- **WHEN** an opportunity card is clicked
|
||||
- **THEN** its details are shown without changing the opportunity in Oracle
|
||||
65
openspec/specs/opportunity-exploration/spec.md
Normal file
65
openspec/specs/opportunity-exploration/spec.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# opportunity-exploration Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
Let users explore Oracle opportunities within a fiscal Reference using consistent filters, totals and sortable tabular data.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Queries use the user's default saved search
|
||||
Opportunity queries SHALL resolve the unique saved search marked `isDefault=true` and use its `savedSearchNumber` in `copiedFrom` for every page. Missing or ambiguous default searches SHALL prevent a dependent opportunity query.
|
||||
|
||||
#### Scenario: Valid default search
|
||||
- **WHEN** saved searches return exactly one valid default
|
||||
- **THEN** the opportunity payload uses `queries/<savedSearchNumber>` and reuses it throughout pagination
|
||||
|
||||
#### Scenario: No valid default
|
||||
- **WHEN** no unique default saved search is returned
|
||||
- **THEN** the extension reports the failure instead of using a hard-coded saved-search identifier
|
||||
|
||||
### Requirement: Opportunities display before background enrichment
|
||||
The extension SHALL collect the opportunity result pages before displaying the ready list, then start Service Request and product enrichment without waiting for them to finish. Responses from an obsolete Reference request SHALL not replace the active result.
|
||||
|
||||
#### Scenario: SR remains pending
|
||||
- **WHEN** opportunity pagination completes and Service Request loading remains pending
|
||||
- **THEN** the opportunity table is already usable
|
||||
|
||||
#### Scenario: Reference changes during loading
|
||||
- **WHEN** an older query completes after a newer Reference query has started
|
||||
- **THEN** the older result does not overwrite the active view
|
||||
|
||||
### Requirement: Reference uses Oracle fiscal periods
|
||||
The selected Reference SHALL determine the query date range using a June-through-May fiscal year. Opportunity type selections SHALL also constrain the query; an empty type selection SHALL show an explanatory empty state without sending an opportunity query.
|
||||
|
||||
#### Scenario: Fiscal first quarter
|
||||
- **WHEN** Reference resolves to the first fiscal quarter
|
||||
- **THEN** the selected period covers June through August with the next quarter boundary excluded
|
||||
|
||||
### Requirement: Filters are coordinated across views
|
||||
Overview and Calendar SHALL share search, Customer, Owner, Status, Stage, eligible SR/Action filters and Booking/Workload filters. Customer options SHALL narrow by selected Owners and Owner options by selected Customers without additional API calls.
|
||||
|
||||
#### Scenario: Customer narrows owner choices
|
||||
- **WHEN** a customer associated with two owners is selected
|
||||
- **THEN** the Owner choices contain the corresponding owners and widening the customer selection restores applicable choices
|
||||
|
||||
#### Scenario: All-selected item is clicked
|
||||
- **WHEN** the user clicks an item while all choices in its multiselect or filter-badge group are selected
|
||||
- **THEN** only that item remains selected and subsequent clicks can add other choices
|
||||
|
||||
#### Scenario: Booking isolation
|
||||
- **WHEN** both Booking and Workload are selected and Booking is clicked
|
||||
- **THEN** only Booking opportunities remain visible in both views
|
||||
|
||||
### Requirement: Overview preserves table meaning and ordering
|
||||
Overview SHALL restore its last sort column and direction, display customer `PartyName`, label win probability `Prob.`, and give Name and Customer greater width priority. Monetary cells and their headers SHALL align right; other headers SHALL align left.
|
||||
|
||||
#### Scenario: Overview reopens
|
||||
- **WHEN** the user reopens Overview after selecting a descending Amount sort
|
||||
- **THEN** that ordering is restored and the displayed amount values determine the order
|
||||
|
||||
### Requirement: Indicators reflect the filtered opportunities
|
||||
The opportunity count and stage amounts SHALL follow the active filters without issuing additional queries solely to calculate the displayed indicators.
|
||||
|
||||
#### Scenario: Local filter changes
|
||||
- **WHEN** the user narrows the loaded list using a Customer filter
|
||||
- **THEN** the count and stage indicators update with the filtered opportunities
|
||||
68
openspec/specs/organization-charts/spec.md
Normal file
68
openspec/specs/organization-charts/spec.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# organization-charts Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
Maintain customer organization charts locally while enriching people with Oracle contact information and related opportunities.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Charts are scoped and stored locally
|
||||
Charts SHALL persist JSON-compatible records in extension-owned IndexedDB, scoped by user and customer in the browser profile. Records SHALL include revision and update metadata; stale saves SHALL be rejected. Email SHALL not persist in chart nodes.
|
||||
|
||||
#### Scenario: Concurrent chart change
|
||||
- **WHEN** a user saves an outdated revision after another window has saved the chart
|
||||
- **THEN** the save is rejected with guidance to reopen the current chart
|
||||
|
||||
#### Scenario: Browser profile is different
|
||||
- **WHEN** the same user accesses the customer in another browser profile
|
||||
- **THEN** this local chart is not automatically synchronized to that profile
|
||||
|
||||
### Requirement: Hierarchy editing preserves remaining people
|
||||
The chart SHALL support adding people, changing their manager, notes, branch expansion/collapse, zoom and panning. It SHALL reject invalid hierarchies, support up to 500 people and 60 levels, and promote direct reports to the removed person's manager when a person is deleted.
|
||||
|
||||
#### Scenario: Manager is deleted
|
||||
- **WHEN** a user deletes a person with direct reports
|
||||
- **THEN** those reports remain in the chart under the deleted person's manager
|
||||
|
||||
#### Scenario: Unsaved chart is closed
|
||||
- **WHEN** the user closes a chart with unsaved changes
|
||||
- **THEN** the extension requests confirmation before discarding those changes
|
||||
|
||||
### Requirement: Contact autocomplete is debounced and customer-scoped
|
||||
Name autocomplete SHALL search contacts after a 350 ms typing pause, filter by the customer's PartyId, display PartyName and JobTitle, and ignore superseded results. Empty queries and opening the chart alone SHALL not issue contact searches.
|
||||
|
||||
#### Scenario: User keeps typing
|
||||
- **WHEN** another character arrives before the search delay expires
|
||||
- **THEN** the pending search is superseded rather than sending one query per character
|
||||
|
||||
### Requirement: Person details refresh contact data on demand
|
||||
Opening a stored person SHALL query contacts using the person's Name as keywords and match by contact PartyId. A matching result SHALL refresh Name and Job Title while preserving notes and reporting relationships; Email SHALL remain transient. Job Title SHALL be eligible for chart persistence.
|
||||
|
||||
#### Scenario: Contact data changed
|
||||
- **WHEN** a matching contact response has a new name or job title
|
||||
- **THEN** the working chart updates those fields and retains the person's notes and manager
|
||||
|
||||
### Requirement: Contact PartyNumber is preserved as an opaque identifier
|
||||
Chart nodes SHALL retain the contact's PartyNumber, including alphanumeric values. Opening person details SHALL persist a returned PartyNumber; opportunity lookup SHALL use an existing stored value and attempt resolution when it is missing.
|
||||
|
||||
#### Scenario: Alphanumeric number is already saved
|
||||
- **WHEN** opportunities are requested for a person with PartyNumber `A4KCS2P`
|
||||
- **THEN** that exact value is used in `OpportunityContact.ContactPartyNumber`, without numeric conversion
|
||||
|
||||
### Requirement: Contact opportunity tables load all pages
|
||||
The person card SHALL provide an opportunities action that opens `Opportunities | <name>`, shows a skeleton while loading and follows `hasMore` until all pages are collected. The resulting table SHALL be sortable and link each Name to its corresponding opportunity in a new tab.
|
||||
|
||||
#### Scenario: Contact has more than one result page
|
||||
- **WHEN** the opportunities response sets `hasMore=true`
|
||||
- **THEN** the next offset is queried using the same contact PartyNumber until the result is complete
|
||||
|
||||
### Requirement: New contacts are created explicitly
|
||||
The contact-creation form SHALL require First Name, Last Name and Email, map email/phone consent to their corresponding Do/DoNot flags and obtain account identifiers from the selected customer. Provided phone components SHALL be combined as country code, hyphen and number. Save SHALL submit directly without a payload-preview step.
|
||||
|
||||
#### Scenario: Optional phone is omitted
|
||||
- **WHEN** required contact fields are valid but a phone number is not filled
|
||||
- **THEN** that absent phone value is not included as a populated contact field
|
||||
|
||||
#### Scenario: Phone components are entered
|
||||
- **WHEN** country code `55` and phone number `99999999999` are provided
|
||||
- **THEN** the submitted raw phone value is `55-99999999999`
|
||||
46
openspec/specs/preferences-cache/spec.md
Normal file
46
openspec/specs/preferences-cache/spec.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# preferences-cache Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
Preserve user preferences and reuse eligible data without allowing expired or invalidated results to silently replace fresh information.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Preferences survive reopening
|
||||
The extension SHALL persist supported filter preferences, theme, opportunity type selections and cache duration in the browser profile. Invalid or unavailable stored values SHALL fall back to usable defaults or in-memory state.
|
||||
|
||||
#### Scenario: Stored preference cannot be read
|
||||
- **WHEN** browser storage is unavailable or a saved preference is invalid
|
||||
- **THEN** the extension remains usable with its fallback rather than failing to open
|
||||
|
||||
### Requirement: Sort preferences belong to individual tables
|
||||
Supported sortable tables SHALL retain their own last sort key and direction without changing other tables' preferences. Product detail tables SHALL remain excluded from this sorting behavior.
|
||||
|
||||
#### Scenario: Two tables use different sorts
|
||||
- **WHEN** the user sorts Installed Base by amount and contact opportunities by close date
|
||||
- **THEN** reopening each table restores its own saved ordering
|
||||
|
||||
### Requirement: Cache reuse respects validity and identity boundaries
|
||||
Product, workload and activity caches SHALL apply their configured lifetimes and existing identity/account/product-update scopes. A missing or expired activity cache SHALL not be represented as a confirmed empty result.
|
||||
|
||||
#### Scenario: Workload token rotates
|
||||
- **WHEN** the same user's account workload data is still valid but the authorization token changes
|
||||
- **THEN** the account data can be reused without treating the token string as a different customer identity
|
||||
|
||||
### Requirement: Only eligible reads are reused
|
||||
Form request caching SHALL reuse only known read operations, share concurrent reads and invalidate applicable entries after successful writes. Create, update and delete operations SHALL not be served from a response cache.
|
||||
|
||||
#### Scenario: Repeated write
|
||||
- **WHEN** the user explicitly submits a new valid write operation
|
||||
- **THEN** the operation goes through the write transport rather than returning a cached success
|
||||
|
||||
### Requirement: Refresh all invalidates reusable data safely
|
||||
Refresh all SHALL invalidate product/activity and related cached data before reloading the active Reference, preserve user preferences and authentication, and prevent pre-invalidation responses from repopulating invalidated cache entries. Cache invalidation errors SHALL be reported.
|
||||
|
||||
#### Scenario: Old product request finishes after refresh
|
||||
- **WHEN** an old request completes after its cache has been invalidated
|
||||
- **THEN** its result does not restore the invalidated cache snapshot
|
||||
|
||||
#### Scenario: Activity updates arrive
|
||||
- **WHEN** only background activity lookup results change
|
||||
- **THEN** those lookups do not independently advance the product Last update timestamp
|
||||
57
openspec/specs/product-workloads/spec.md
Normal file
57
openspec/specs/product-workloads/spec.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# product-workloads Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
Enrich opportunities with products and workload information and support review and explicit updates of consumption projections.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Product enrichment runs in the background
|
||||
Product loading SHALL update opportunity product counts and progress without blocking the displayed opportunity list. Product detail tables SHALL retain their source order rather than applying the general table sorting preference.
|
||||
|
||||
#### Scenario: Some products are still loading
|
||||
- **WHEN** opportunities are visible and their products have not all arrived
|
||||
- **THEN** completed product results update their related opportunities while remaining products continue loading
|
||||
|
||||
### Requirement: Workload retrieval is shared by customer
|
||||
Workload retrieval SHALL consolidate all result pages for each distinct customer account, reuse eligible cached results and correlate workloads to products by revenue identifier. Concurrent consumers of the same account SHALL share loading.
|
||||
|
||||
#### Scenario: Multiple opportunities share a customer
|
||||
- **WHEN** their products require workloads for the same account
|
||||
- **THEN** one shared account retrieval supplies the matching products and continues while the response indicates more pages
|
||||
|
||||
### Requirement: Booking classification requires loaded products without Workload names
|
||||
An opportunity with a nonempty loaded product list SHALL display a distinct Booking badge when every product has a blank or `-` Workload name. If any product has a Workload name, the existing ramp badge behavior SHALL remain.
|
||||
|
||||
#### Scenario: No products have an assigned Workload
|
||||
- **WHEN** all loaded products have blank or `-` Workload names
|
||||
- **THEN** Booking replaces Ramp Months and the opportunity matches the Booking filter
|
||||
|
||||
#### Scenario: Mixed product assignments
|
||||
- **WHEN** at least one product has a Workload name
|
||||
- **THEN** the opportunity retains its ramp behavior and is not classified as Booking
|
||||
|
||||
### Requirement: Projection access is independent of a difference alert
|
||||
Clicking a ramp badge SHALL open consumption projection even when forecast and calculated amounts match. Difference alerts SHALL be placed between ramp and SR badges; product alerts without a workload record SHALL indicate unavailability with disabled styling.
|
||||
|
||||
#### Scenario: Forecast matches calculation
|
||||
- **WHEN** the user clicks a ramp badge for a product with no forecast difference
|
||||
- **THEN** Consumption projection still opens
|
||||
|
||||
### Requirement: Projection comparison uses calculated monthly values
|
||||
Consumption projection SHALL calculate monthly amounts using adjusted ACR, ramp months and first-month proration, and compare forecast minus calculated amounts at cent precision.
|
||||
|
||||
#### Scenario: Monthly discrepancy
|
||||
- **WHEN** a calculated monthly amount differs from its forecast after rounding to cents
|
||||
- **THEN** the comparison shows the difference and enables the corresponding alert
|
||||
|
||||
### Requirement: Estimate updates require confirmation
|
||||
Update estimates SHALL ask for confirmation before writing calculated values to SPA, prevent duplicate submissions and report success or failure. Successful updates SHALL refresh the comparison and invalidate affected workload cache data.
|
||||
|
||||
#### Scenario: Confirmation is cancelled
|
||||
- **WHEN** the user declines the update confirmation
|
||||
- **THEN** no forecast update is sent
|
||||
|
||||
#### Scenario: Confirmed update succeeds
|
||||
- **WHEN** the user confirms and the update request succeeds
|
||||
- **THEN** the comparison reflects the new values and subsequent workload reads do not reuse the invalidated values
|
||||
53
openspec/specs/request-debugging/spec.md
Normal file
53
openspec/specs/request-debugging/spec.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# request-debugging Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
Make extension HTTP activity inspectable without pre-rendering an ever-growing request interface or confusing cached data with new network operations.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: HTTP activity has a visible lifecycle
|
||||
Debug Requests SHALL record request identity, method, URL, timing, headers, body, response and final status when available. Running requests SHALL transition to success or failure, cache hits SHALL not create fictitious HTTP requests, and entries SHALL be grouped by request category.
|
||||
|
||||
#### Scenario: Request is pending
|
||||
- **WHEN** a logged request has started but not completed
|
||||
- **THEN** it is displayed as running with its start time and later updates with completion or failure
|
||||
|
||||
### Requirement: Request history is persisted per tab context
|
||||
Request records SHALL be stored in page localStorage under a tab-specific namespace. Closing the main modal SHALL preserve them. Starting page one of a new opportunity query SHALL reset that history; later pages of the same query SHALL retain it.
|
||||
|
||||
#### Scenario: Modal closes and reopens
|
||||
- **WHEN** the main modal closes and reopens without a new opportunity query
|
||||
- **THEN** the existing debug history remains available
|
||||
|
||||
#### Scenario: New query begins
|
||||
- **WHEN** the first opportunity page is about to be sent
|
||||
- **THEN** old history is cleared for that tab without deleting preferences or another tab's debug records
|
||||
|
||||
### Requirement: Debug rendering is deferred
|
||||
The hidden debug view SHALL avoid constructing request-detail DOM. Opening the view SHALL render request summaries and expanding a request SHALL construct its details, preserving expansion and scroll state across updates where applicable.
|
||||
|
||||
#### Scenario: Requests accumulate while debug is closed
|
||||
- **WHEN** requests complete while the debug panel is hidden
|
||||
- **THEN** records are captured without mounting their detail elements in the hidden panel
|
||||
|
||||
### Requirement: Debug access stays above other extension views
|
||||
Ctrl+Shift+D SHALL toggle Debug Requests as a full-page extension view above other extension modals. Closing it SHALL return to the underlying view without opening a browser tab or native fullscreen mode.
|
||||
|
||||
#### Scenario: Debug opens over person details
|
||||
- **WHEN** the user presses Ctrl+Shift+D while a nested modal is open
|
||||
- **THEN** Debug Requests appears in front of that modal
|
||||
|
||||
### Requirement: Sensitive-value masking is a display control
|
||||
Debug SHALL hide sensitive values by default and support explicit reveal of retained originals. Documentation SHALL distinguish masking from storage protection: captured debug records can retain sensitive response values and masking SHALL not be described as encryption or guaranteed redaction at rest.
|
||||
|
||||
#### Scenario: Identity token is captured
|
||||
- **WHEN** the identity response includes a token
|
||||
- **THEN** normal debug display hides the token and the explicit visibility control can reveal its retained value
|
||||
|
||||
### Requirement: Debug failures do not interrupt application requests
|
||||
Unavailable or full localStorage SHALL leave records available in memory with explanatory feedback. Debug timers and persistence errors SHALL not prevent the underlying network request from starting or completing.
|
||||
|
||||
#### Scenario: Storage quota is exhausted
|
||||
- **WHEN** persisting a request record fails due to localStorage quota
|
||||
- **THEN** the request outcome remains available in memory and the application request continues normally
|
||||
57
openspec/specs/service-requests/spec.md
Normal file
57
openspec/specs/service-requests/spec.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# service-requests Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
Expose service requests linked to opportunities and customers, with progressive status badges, detail views and explicit record creation.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: CRM SR queries resolve their saved search
|
||||
Before the first CRM Service Request page, the extension SHALL retrieve SR search resources using the general Token Relay Bearer and use the first item's valid `savedSearchNumber` as `queries/<savedSearchNumber>` in `copiedFrom`.
|
||||
|
||||
#### Scenario: Search resources have no identifier
|
||||
- **WHEN** the first item has no valid saved-search number
|
||||
- **THEN** the dependent CRM SR query fails explicitly instead of using a fixed fallback
|
||||
|
||||
### Requirement: SR enrichment is progressive and nonblocking
|
||||
For eligible users, CRM SR pages SHALL load after opportunities are displayed and update their linked badges in the background. The query SHALL select pending-delivery team SRs and match opportunities through the returned opportunity number.
|
||||
|
||||
#### Scenario: First SR page arrives
|
||||
- **WHEN** more SR pages remain after the first successful page
|
||||
- **THEN** information received so far can update the visible opportunities without waiting for all pages
|
||||
|
||||
### Requirement: Failed SR loading remains distinguishable from no matches
|
||||
The extension SHALL distinguish loading, failed and confirmed empty SR results. Pagination SHALL detect lack of progress, retry each failed page at most five total attempts, and stop work superseded by a newer query.
|
||||
|
||||
#### Scenario: SR lookup fails
|
||||
- **WHEN** a lookup cannot establish whether an opportunity has matching SRs
|
||||
- **THEN** its badge indicates an unknown or failed state rather than confirmed absence
|
||||
|
||||
#### Scenario: Successful SR snapshot is reused
|
||||
- **WHEN** a subsequent cycle can reuse the completed SR result within the current page session
|
||||
- **THEN** it does not repeat the completed query unless explicitly invalidated
|
||||
|
||||
### Requirement: Customer SR details use the resolved account identifier
|
||||
Customer Service Requests SHALL resolve account summary first, use its `id` for the customer SR query and consolidate pages of open SRs. The dialog SHALL provide a loading skeleton, searchable sortable results, and guards against late results after closure.
|
||||
|
||||
#### Scenario: Account has distinct identifiers
|
||||
- **WHEN** account summary returns different `id` and `registryId` values
|
||||
- **THEN** customer SR retrieval uses `id`, not `registryId`
|
||||
|
||||
### Requirement: Internal SR recovery is bounded
|
||||
Internal SR details SHALL report failed requests and use bounded, shared session recovery rather than continuously issuing requests or opening a visible recovery tab.
|
||||
|
||||
#### Scenario: Endpoint remains unavailable
|
||||
- **WHEN** an Internal SR read continues to fail after its allowed recovery attempts
|
||||
- **THEN** the view shows failure and does not keep sending an unbounded automatic request loop
|
||||
|
||||
### Requirement: SR creation validates before writing
|
||||
Service Request creation SHALL require valid form inputs before submission, retain entered data on failure and prevent duplicate submissions while saving. Internal SR creation SHALL resolve parent SR and current resource information before linking the new record to its parent.
|
||||
|
||||
#### Scenario: Required fields are missing
|
||||
- **WHEN** Save is clicked on an incomplete SR form
|
||||
- **THEN** the missing fields are highlighted and no create request is sent
|
||||
|
||||
#### Scenario: Create request fails
|
||||
- **WHEN** a submitted SR creation fails
|
||||
- **THEN** the user receives error feedback and their form values remain available
|
||||
56
openspec/specs/session-authentication/spec.md
Normal file
56
openspec/specs/session-authentication/spec.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# session-authentication Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
Establish authenticated Oracle access before dependent data operations while preserving credential boundaries and profile restrictions.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Valid identity precedes dependent data requests
|
||||
The extension SHALL obtain a successful current-user response containing a valid user identifier, name, roles array and token before starting dependent opportunity or activity data requests. Concurrent identity consumers SHALL share acquisition, and invalid responses SHALL retry with backoff.
|
||||
|
||||
#### Scenario: HTML is returned with HTTP 200
|
||||
- **WHEN** current-user acquisition receives a login document instead of the required JSON
|
||||
- **THEN** dependent data requests remain blocked and identity acquisition retries
|
||||
|
||||
#### Scenario: Identity is already established
|
||||
- **WHEN** the user changes Reference or reopens the main modal in the same page session
|
||||
- **THEN** the extension reuses the successful identity without another current-user HTTP request
|
||||
|
||||
### Requirement: SPA recovery verifies the loaded session page
|
||||
SPA session recovery SHALL open the configured bootstrap URL in an inactive auxiliary tab and verify page readiness before probing identity. Login forms, error documents and OAuth callbacks SHALL not count as a ready SPA page.
|
||||
|
||||
#### Scenario: Recovery navigation
|
||||
- **WHEN** identity recovery requires a SPA session
|
||||
- **THEN** navigation starts at `https://spa.oracle.com/oalcrm/web/api/g2m-consumer-application/ui/index.html?ojr=whitespace`
|
||||
- **AND** the extension preserves the originating browser context and closes its owned auxiliary tab when recovery finishes
|
||||
|
||||
#### Scenario: Rejected callback document
|
||||
- **WHEN** recovery encounters an authorization-error callback
|
||||
- **THEN** it restarts from the configured bootstrap URL instead of replaying that callback as a successful session
|
||||
|
||||
### Requirement: SR session preparation has independent progress
|
||||
SR session preparation SHALL be able to run concurrently with SPA identity preparation, using the SeaaS external application URL. It SHALL expose completion or failure and allow a user retry after failure.
|
||||
|
||||
#### Scenario: SR preparation fails
|
||||
- **WHEN** preparation through `https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/SeaaS_initiation/live/webApps/external/` fails or reaches its 70-second timeout
|
||||
- **THEN** the extension offers retry rather than declaring the SR session ready
|
||||
|
||||
### Requirement: SALES_REP activity access is restricted
|
||||
For a user whose roles include `SALES_REP`, the extension SHALL hide CRM SR and Workload Action badges and Manage Time access, and SHALL not issue their dependent activity or Manage Time data requests.
|
||||
|
||||
#### Scenario: Restricted user after successful authentication
|
||||
- **WHEN** identity resolves with the `SALES_REP` role
|
||||
- **THEN** opportunities remain available but CRM activity badges and Manage Time are unavailable
|
||||
- **AND** attempting to open Manage Time does not load its data
|
||||
|
||||
### Requirement: Credentials are specific to each Oracle service
|
||||
The extension SHALL preserve operation-specific credentials and cookie inclusion. It SHALL use the general Token Relay Bearer for Fusion queries and the appropriate SPA consumer authorization for each SPA service rather than substituting token families.
|
||||
|
||||
#### Scenario: Customer SR authorization
|
||||
- **WHEN** customer service requests are loaded using SPA-ORANGE authorization
|
||||
- **THEN** the raw authorization value is sent in `custsr-auth` without a Bearer prefix
|
||||
|
||||
#### Scenario: Token Relay does not finish
|
||||
- **WHEN** a Token Relay request exceeds its request timeout
|
||||
- **THEN** the attempt reports failure instead of remaining indefinitely pending in Debug Requests
|
||||
42
openspec/specs/workload-actions/spec.md
Normal file
42
openspec/specs/workload-actions/spec.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# workload-actions Specification
|
||||
|
||||
## Purpose
|
||||
|
||||
Identify workload actions owned by the signed-in user and allow eligible users to create actions for opportunity products.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Action enrichment respects prerequisite data
|
||||
Workload Action enrichment SHALL use distinct product revenue identifiers after the product cycle and successful or reused CRM SR loading. Unavailable SR data SHALL leave action state unknown rather than treating it as an empty result.
|
||||
|
||||
#### Scenario: SR prerequisite fails
|
||||
- **WHEN** CRM SR loading fails for a completed product cycle
|
||||
- **THEN** action enrichment is blocked and its badges do not assert that no actions exist
|
||||
|
||||
### Requirement: Ownership determines the action badge
|
||||
The action badge SHALL aggregate returned actions for the opportunity products and mark a match when an action owner equals the general Token Relay principal. Missing principal or failed lookups SHALL not count as confirmed nonmatches.
|
||||
|
||||
#### Scenario: Actions exist for other owners
|
||||
- **WHEN** returned actions have no owner matching the known principal
|
||||
- **THEN** the badge indicates no matching ownership while its tooltip retains the returned actions
|
||||
|
||||
### Requirement: Read attempts are bounded and partial coverage is disclosed
|
||||
Each action lookup SHALL make at most five total attempts and stop on success or session supersession. The current lookup SHALL expose `hasNext` as additional unqueried actions rather than implying that all pages were loaded.
|
||||
|
||||
#### Scenario: More action pages exist
|
||||
- **WHEN** a successful action response sets `hasNext=true`
|
||||
- **THEN** the tooltip states that additional actions exist and pagination is not enabled
|
||||
|
||||
### Requirement: Action forms use validated lookup selections
|
||||
The Action form SHALL load team members and lookup values with the workload credential, support searchable selections, and submit selected codes rather than arbitrary typed search text. Required inputs and the date range SHALL be validated before Save.
|
||||
|
||||
#### Scenario: Search text is not an option
|
||||
- **WHEN** the user types a value without selecting a valid lookup result
|
||||
- **THEN** the text is not submitted as a valid option value
|
||||
|
||||
### Requirement: Action creation is explicit and preserves failure state
|
||||
Saving a valid action SHALL send current-user attribution, UTC dates and a notes array, lock duplicate submission while pending and show a result toast. A failed create SHALL retain the form without automatically retrying the POST.
|
||||
|
||||
#### Scenario: Create fails
|
||||
- **WHEN** the server rejects an action creation
|
||||
- **THEN** the form remains available with the entered data and no automatic duplicate POST is issued
|
||||
Reference in New Issue
Block a user