Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-07-25
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
## Context

The frontend receives provider and tool catalogs dynamically, but it keeps static TypeScript contracts and field lists for persisted user settings, tool purposes, category grouping, translations, and provider icons. The backend now returns provider ID `twelve-data`, settings fields `twelve_data_api_key` and `tool_choice_api_stock_quote`, tool type `api_stock_quote`, and additional asset/stock errors. Without matching static entries, the provider can appear but its credential and tool choice cannot be saved, and the stock tool is intentionally hidden when translations are absent.

The frontend also maps numeric API errors locally. Backend code `6002` historically represented insufficient credits and remains supported by the frontend, while stock quote rate limiting has been assigned the new unique backend code `6003`.

## Goals / Non-Goals

**Goals:**

- Make Twelve Data credentials fully editable, mask-aware, clearable, and persistable through the existing access-settings flow.
- Make the stock-quote tool visible and configurable through presets and custom intelligence settings.
- Keep every API error code mapped once with matching semantics and complete localization.
- Provide a temporary deterministic Twelve Data icon without blocking implementation on the final brand asset.

**Non-Goals:**

- Add a stock-price lookup page, price-alert page, or new HTTP client endpoint.
- Reimplement stock lookup, alert logic, or provider validation in the frontend.
- Change provider metadata that is already supplied by the backend, including the API-key URL.
- Add a new test framework or runtime dependency.

## Decisions

### 1. Extend the existing settings contract symmetrically

Add `twelve_data_api_key` and `tool_choice_api_stock_quote` everywhere their CoinMarketCap and cryptocurrency-tool counterparts participate: response and payload types, provider-to-setting mapping, masked-field diffing, string-field diffing, API-key detection, and bulk clearing.

This preserves the existing sparse PATCH behavior. A provider-specific form or separate stock settings service would duplicate the access-settings flow and is unnecessary.

### 2. Continue consuming provider metadata dynamically

Use backend provider ID `twelve-data`; continue displaying its backend-supplied name, token format, `Stocks` label, and `https://twelvedata.com/account/api-keys` management URL. Only the field mapping and icon remain frontend-owned.

Hard-coding the URL or provider display metadata again in the frontend would create an avoidable second source of truth.

### 3. Integrate stock quotes into the existing tool taxonomy

Add `api_stock_quote` to `ToolType`, place it in the integrations category and changed-state map, assign a stock-market icon, and add its title and description to all locales. The user-facing title uses the natural local equivalent of “Stocks and stock market,” including exact Serbian title `Akcije i berza`, rather than a literal translation of the provider operation “stock quote.” Preset comparison and application continue using the existing dynamic `tool_choice_${toolType}` convention once the typed settings field exists.

### 4. Use a clearly named temporary provider asset

Copy `coinmarketcap-white.svg` to a distinct Twelve Data asset path and map `twelve-data` to that copy. The duplicate is intentional and temporary: callers reference the correct provider-specific filename now, so replacing the artwork later changes only the asset contents.

The last implementation task is a manual TODO for the user to provide and review the real Twelve Data icon. The temporary asset remains until that separate input is available.

### 5. Preserve the existing error mapping shape while auditing it mechanically

Keep `getErrorTranslationKey` as the central numeric mapping and add missing current backend codes exactly once. Rename the semantic key for `4003` to `invalid_resource_token`; add the previously omitted `1039`; add asset/stock codes `1040`, `1041`, `1042`, `2014`, `5014`, and `6003`; and retain `6002` solely as a documented legacy insufficient-credit mapping.

All mapped keys are added to every locale, and the normal i18n lint regenerates the typed translation-key union. A deterministic comparison against the backend constants verifies completeness, uniqueness, and the single documented legacy exception.

## Risks / Trade-offs

- [The copied CoinMarketCap artwork can misrepresent Twelve Data] → Use a distinct filename, call it temporary in the task record, and stop at a final manual replacement TODO.
- [Static frontend settings lists can drift again] → Update every symmetric list in one task and verify key save, clear, and preset paths during review.
- [Legacy `6002` makes a strict set comparison report one frontend-only code] → Treat it as the only documented legacy exception; current stock rate limiting uses unique code `6003`.
- [Missing locale entries cause the stock tool to disappear] → Update all locales before running i18n lint and verify the rendered tool group exists.

## Migration Plan

Deploy the backend containing stock code `6003` before or with this frontend. The frontend remains compatible with older insufficient-credit responses through `6002`. Rollback requires only reverting the frontend; unknown Twelve Data fields returned by the backend are otherwise ignored.

## Open Questions

- The final Twelve Data icon asset is pending from the user and will replace the temporary copied artwork after the implementation review.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## Why

The backend now exposes Twelve Data credentials, stock-quote tool selection, and stock-specific structured errors, but the frontend cannot persist those settings or display that tool. The frontend error-code catalog has also drifted from the backend, including a historical collision at code `6002`, so the contracts need to be aligned before the feature is exposed.

## What Changes

- Add Twelve Data API-key and stock-quote tool-choice fields to the frontend settings contracts and changed-payload handling.
- Display Twelve Data in access settings using the provider metadata supplied by the backend.
- Add stock quotes to the advanced tool selector, preset comparison, changed-state tracking, icons, and every supported locale.
- Temporarily copy the existing CoinMarketCap icon for Twelve Data so the provider has a deterministic visual until the real asset is supplied.
- Align frontend API error mappings with the backend, retain `6002` only for legacy insufficient-credit responses, and map stock quote rate limiting to the new unique code `6003`.
- Add every new or renamed error translation to all supported locales and regenerate the typed translation-key catalog.
- End implementation with a manual TODO for the user to supply and review the real Twelve Data icon before the placeholder is replaced.

## Capabilities

### New Capabilities

- `stock-quote-settings`: Frontend support for configuring a Twelve Data key and selecting the stock-quote tool through the existing access and intelligence settings flows.
- `api-error-code-alignment`: Complete, duplicate-free frontend mapping of backend API error codes, including localized stock-price errors and explicit legacy-code handling.

### Modified Capabilities

None.

## Impact

- Affects user-settings and external-tools service types, changed-payload construction, access-key clearing, advanced tool grouping, provider/tool icons, error parsing, and all locale files.
- Consumes the backend fields `twelve_data_api_key` and `tool_choice_api_stock_quote`, provider ID `twelve-data`, tool type `api_stock_quote`, and stock error codes.
- Adds no runtime dependency and no new user-facing HTTP endpoint.
- Requires frontend lint and production build validation.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
## ADDED Requirements

### Requirement: Complete API error mapping
The frontend SHALL map every current backend API error code to exactly one semantic translation key and SHALL contain no duplicate numeric cases.

#### Scenario: Current backend error is received
- **WHEN** an API response contains a numeric code defined by the backend error-code catalog
- **THEN** `getErrorTranslationKey` SHALL return the corresponding semantic translation key

#### Scenario: Error catalog is audited
- **WHEN** frontend validation compares the mapping with the backend catalog
- **THEN** it SHALL report no missing current codes, no duplicate numeric mappings, and no undocumented frontend-only codes

### Requirement: Corrected existing error mappings
The frontend SHALL map code `1039` to `unsupported_media_type` and code `4003` to `invalid_resource_token`.

#### Scenario: Unsupported media is returned
- **WHEN** the backend returns error code `1039`
- **THEN** the frontend SHALL display the localized unsupported-media message

#### Scenario: Resource token is invalid
- **WHEN** the backend returns error code `4003`
- **THEN** the frontend SHALL display the localized invalid-resource-token message

### Requirement: Asset and stock error mappings
The frontend SHALL map `1040` to `invalid_asset_type`, `1041` to `invalid_asset_amount`, `1042` to `invalid_stock_symbol`, `2014` to `stock_quote_not_found`, `5014` to `stock_quote_failed`, and `6003` to `stock_quote_rate_limited`.

#### Scenario: Asset validation fails
- **WHEN** the backend returns code `1040`, `1041`, or `1042`
- **THEN** the frontend SHALL display the corresponding localized validation message

#### Scenario: Stock provider operation fails
- **WHEN** the backend returns code `2014`, `5014`, or `6003`
- **THEN** the frontend SHALL display the corresponding localized not-found, provider-failure, or rate-limit message

### Requirement: Explicit legacy code compatibility
The frontend SHALL retain code `6002` as the sole documented frontend-only legacy mapping and SHALL interpret it only as `insufficient_credits`; current stock rate limiting SHALL use `6003`.

#### Scenario: Legacy insufficient-credit response is received
- **WHEN** an older backend returns code `6002`
- **THEN** the frontend SHALL display the insufficient-credits message

#### Scenario: Current stock rate limit is received
- **WHEN** the current backend returns code `6003`
- **THEN** the frontend SHALL display the stock-quote-rate-limited message without colliding with legacy code `6002`

### Requirement: Localized API errors
Every API error translation key used by the mapping SHALL exist in every supported locale and in the generated typed translation-key catalog.

#### Scenario: New error is displayed in any locale
- **WHEN** a user receives an asset, stock, media, or resource-token error in any supported language
- **THEN** the frontend SHALL render localized text rather than a missing key

#### Scenario: Unknown error code is received
- **WHEN** an API response contains an unmapped code
- **THEN** the existing unknown-error fallback SHALL remain in effect
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
## ADDED Requirements

### Requirement: Twelve Data credential settings
The frontend SHALL represent `twelve_data_api_key` in user settings and sparse update payloads and SHALL associate backend provider ID `twelve-data` with that field.

#### Scenario: Existing credential is loaded
- **WHEN** the user-settings API returns a masked Twelve Data credential
- **THEN** the access page SHALL display the masked value for the Twelve Data provider without treating it as a local change

#### Scenario: Credential is saved
- **WHEN** a user enters or replaces a Twelve Data credential
- **THEN** the frontend SHALL send `twelve_data_api_key` in the sparse settings PATCH payload

#### Scenario: Credential is cleared
- **WHEN** a user clears Twelve Data individually or uses the remove-all-keys action
- **THEN** the frontend SHALL send an empty `twelve_data_api_key` and SHALL include that removal in changed-state detection

### Requirement: Backend-owned Twelve Data metadata
The frontend SHALL display the Twelve Data name, key-management URL, token format, and tool labels from the external-provider response rather than duplicating those values locally.

#### Scenario: Provider catalog is displayed
- **WHEN** the external-tools API returns provider ID `twelve-data`
- **THEN** the access page SHALL render the provider using the returned metadata, including `https://twelvedata.com/account/api-keys`

### Requirement: Stock quote tool choice
The frontend SHALL support `api_stock_quote` as an integrations tool type and SHALL persist its selection through `tool_choice_api_stock_quote`.

#### Scenario: Stock quote tool is returned
- **WHEN** the external-tools API returns a tool with type `api_stock_quote`
- **THEN** the advanced tool panel SHALL render a localized stock-quote section in the integrations category

#### Scenario: Custom stock quote choice is saved
- **WHEN** a user changes the stock-quote tool selection
- **THEN** changed-state detection SHALL activate and the sparse settings PATCH SHALL contain `tool_choice_api_stock_quote`

#### Scenario: Preset includes stock quotes
- **WHEN** the selected intelligence preset contains an `api_stock_quote` choice
- **THEN** preset application and preset detection SHALL include the stock-quote setting

### Requirement: Stock quote localization
Every supported locale SHALL provide a natural local equivalent of “Stocks and stock market” as the title and a localized description for `tools.types.api_stock_quote`, and the generated translation-key type SHALL contain both keys. The Serbian title SHALL be exactly `Akcije i berza`.

#### Scenario: Any supported locale is active
- **WHEN** the intelligence page renders the stock-quote tool
- **THEN** it SHALL show the natural localized “Stocks and stock market” title and description rather than a literal provider-operation label, hiding the type, or displaying a raw key

### Requirement: Temporary Twelve Data icon
The frontend SHALL map provider ID `twelve-data` to a provider-specific asset path that temporarily contains a copy of the existing CoinMarketCap icon.

#### Scenario: Temporary icon is rendered
- **WHEN** Twelve Data appears in access or intelligence settings before the real icon is supplied
- **THEN** the frontend SHALL render the temporary provider asset instead of the generic unknown-provider icon

#### Scenario: Real icon becomes available
- **WHEN** the user supplies and approves the real Twelve Data artwork
- **THEN** the temporary asset contents SHALL be replaced without changing provider IDs or component logic
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## 1. Twelve Data access settings

- [x] 1.1 Add `twelve_data_api_key` to the user settings response/payload contracts, map provider ID `twelve-data`, and include the field in masked diffing, API-key detection, and sparse PATCH construction.
- [x] 1.2 Add `twelve_data_api_key` to the remove-all-keys flow and verify individual save, masked reload, individual clear, and bulk clear produce the intended sparse payloads.
- [x] 1.3 Copy `coinmarketcap-white.svg` to a provider-specific temporary Twelve Data asset path and map `twelve-data` to that asset without hard-coding provider metadata or the key-management URL.

## 2. Stock quote tool settings

- [x] 2.1 Add `api_stock_quote` to `ToolType` and `tool_choice_api_stock_quote` to user settings response/payload contracts and string-field changed-payload handling.
- [x] 2.2 Add `api_stock_quote` to the integrations category, changed-category detection, and tool icon mapping so custom selections and preset comparison/application include stock quotes.
- [x] 2.3 Add the natural local equivalent of “Stocks and stock market” and a description under `tools.types.api_stock_quote` in every supported locale, using exact Serbian title `Akcije i berza`, preserving locale key ordering, and allowing the normal lint task to regenerate typed translation keys.

## 3. API error-code alignment

- [x] 3.1 Update `getErrorTranslationKey` for `1039`, `1040`, `1041`, `1042`, `2014`, `4003`, `5014`, and `6003`; retain `6002` only as the documented legacy insufficient-credit mapping.
- [x] 3.2 Add or rename the corresponding semantic error keys in every supported locale, including `invalid_resource_token`, and regenerate the typed translation-key catalog through the normal lint workflow.
- [x] 3.3 Mechanically compare the frontend mapping with the backend error-code catalog and confirm every current backend code is mapped exactly once, numeric cases contain no duplicates, all translation keys exist in every locale, and `6002` is the only documented legacy frontend-only exception.

## 4. Validation and icon handoff

- [x] 4.1 Run `bun run lint` and `bun run build` from the frontend repository, run `git diff --check`, and resolve all regressions without adding a new test framework.
- [x] 4.2 Manually review the Twelve Data access card, masked-key save/clear behavior, stock-quote custom choice and presets, localized tool visibility, provider navigation, and representative new API error mappings.
- [x] 4.3 **TODO — STOP for the user to supply and approve the real Twelve Data icon. Keep the copied CoinMarketCap artwork explicitly temporary; once the real asset is supplied, replace only the provider-specific asset contents and rerun lint, build, and visual review before completing the change.**
46 changes: 0 additions & 46 deletions openspec/specs/translation-key-ordering/spec.md

This file was deleted.

Loading
Loading