Skip to content

Promote staging to main: portfolio monitors, watchlist tools, and records refresh#130

Merged
TradingGoose-Dev merged 5 commits into
mainfrom
staging
May 30, 2026
Merged

Promote staging to main: portfolio monitors, watchlist tools, and records refresh#130
TradingGoose-Dev merged 5 commits into
mainfrom
staging

Conversation

@TradingGoose-Dev
Copy link
Copy Markdown
Contributor

Summary

Promotes the current staging branch to main with three merged feature sets:

  • Refreshes the Records order table/details experience, including provider order detail access and cleaner linked log handling.
  • Adds workflow watchlist automation through a Watchlist block, watchlist tools, and shared structured listing identity flows.
  • Generalizes monitor support from indicator-only monitors to source-aware indicator and portfolio monitors, including portfolio monitor configuration, runtime dispatch, socket reconciliation, and workflow trigger support.

Diff scope: upstream/main 605fd3f0 to upstream/staging 8a60dd62, 317 files changed.

Why

This promotes staged trading workflow improvements into main so production can use the latest records UI, watchlist automation, shared listing/provider selectors, and portfolio state monitor runtime.

Affected Areas

  • apps/tradinggoose
  • apps/docs
  • packages/*
  • Workflows / execution
  • Realtime / sockets
  • Market data / charting
  • Dev tooling / CI / infra
  • Documentation only
  • Other: changelog/*

Issue Links( if any )

Refs #127
Refs #128
Refs #129

Validation

git fetch --all --prune
git log --oneline upstream/main..upstream/staging
git diff --shortstat upstream/main...upstream/staging
git diff --stat upstream/main...upstream/staging
git diff --name-only upstream/main...upstream/staging | rg '(^|/)migration(s)?(/|$)'

Results:

Risk / Rollout Notes

  • Roll out app, socket server, and background workers together because portfolio monitor runtime, reconcile routes, and pending monitor execution handling are coupled.
  • Monitor APIs move from indicator-specific routes to source-aware /api/monitors routes.
  • Trading holdings naming is replaced by portfolio detail naming across blocks, tools, API routes, and provider capability contracts.
  • Watchlist automation now depends on structured listing identity instead of raw symbols or item ids.
  • Backout: roll back this promotion to the current main deployment. No database migrations or env changes are included, so rollback should not require schema backout.

Config / Data Changes

  • Env vars added or changed: none.
  • Database schema or migration impact: none; no migration files touched.
  • External services or provider behavior changed: trading provider capability naming and provider/account selection flows are updated; broker portfolio detail/order detail paths use the newer canonical provider contracts.

Screenshots / Video

Not captured in this PR body drafting pass.

Visible UI areas changed:

  • Records order table/details panel
  • Monitor configuration/editor surfaces
  • Watchlist listing controls
  • Shared market/trading provider selectors
  • Workflow listing/provider sub-block controls

Checklist

  • I kept the change focused and reviewed my own diff
  • I validated the change locally and documented the results above
  • I updated docs, examples, or copy if behavior/user-facing flows changed
  • I called out any env, schema, provider, or rollout impact
  • I did not include secrets, tokens, or private credentials in this PR

BWJ2310-backup and others added 3 commits May 25, 2026 13:02
* feat(trading): refresh order records table and details

Co-authored-by: Codex <codex@openai.com>

* feat(records): keep order details accessible in linked log view

Co-authored-by: Codex <codex@openai.com>

* refactor(trading): consolidate provider order detail types

Co-authored-by: Codex <codex@openai.com>

---------

Co-authored-by: Codex <codex@openai.com>
* feat(tradinggoose): add watchlist block and tools

Co-authored-by: Codex <codex@openai.com>

* feat(tradinggoose): unify listing selector identity flows

Co-authored-by: Codex <codex@openai.com>

* feat(watchlist): align watchlist tools with canonical routes

Co-authored-by: Codex <codex@openai.com>

* feat(listing-selector): enhance disabled state logic and handle listing options error

* feat(watchlist): refactor code for improved readability and consistency

* fix(editor-workflow): preserve tool sub-block context

Pass operation-aware context into tool sub-blocks and avoid clearing listing selectors before fetched options resolve.\n\nCo-authored-by: Codex <codex@openai.com>

* fix(watchlist): reject unresolved listing options

Co-authored-by: Codex <codex@openai.com>

* feat(listing-selector): support provider-aware listing search

Co-authored-by: Codex <codex@openai.com>

* feat(trading-action): add provider parameter to TradingActionParams and update related tests

* feat(watchlist): enhance listing display options and add tests for listing selector

* feat(listing-selector): rename StockSelector to ListingSearchInput and update references

* refactor(listing-selector): simplify dropdown and input components, remove unused props

* feat(watchlist-tool): add workflow block and tools for managing watchlists and listings

* feat(listing-selector): improve candidate listings handling and enhance summary row component

* feat(listing-selector): refactor fetchOptions handling and improve context value management

---------

Co-authored-by: Codex <codex@openai.com>
* feat(monitors): add portfolio monitor support

Co-authored-by: Codex <codex@openai.com>

* refactor(tradinggoose): move shared widget controls to components

Co-authored-by: Codex <codex@openai.com>

* feat(tradinggoose): split market and trading provider handling

Co-authored-by: Codex <codex@openai.com>

* refactor(monitors): normalize provider configs and sources

Co-authored-by: Codex <codex@openai.com>

* refactor(workflow): inline provider selector sub-blocks

Co-authored-by: Codex <codex@openai.com>

* feat(monitors): add source-aware monitor handling and runtime locks

Co-authored-by: Codex <codex@openai.com>

* feat(portfolio): enhance credential handling in portfolio identity functions

* feat(monitor): remove referenceData from monitor payload functions

* feat(portfolio): enhance service ID resolution and preserve runtime state in portfolio monitor updates

* feat(trading): rename holdings surface to portfolio detail

Co-authored-by: Codex <codex@openai.com>

* fix(monitor): refine config defaults and selector layouts

Co-authored-by: Codex <codex@openai.com>

* fix(monitor-runtime): ignore deduped pending executions

Co-authored-by: Codex <codex@openai.com>

* refactor(monitor): simplify monitor card surfaces

Co-authored-by: Codex <codex@openai.com>

* style(card): adjust card background and shadow for improved aesthetics

* feat(monitor-runtime): add updatedAt field and enhance runtime state management

* feat(monitor-runtime): enhance execution ID generation and improve error handling for database connection issues

* refactor(monitor): simplify MonitorKanbanSection and remove unused props
refactor(config): streamline ConfigBoardSection structure and update tests
feat(tests): enhance portfolio monitor runtime tests with additional error handling

* feat(monitor-config): enhance PortfolioMonitorProviderConfig schema and improve runtime configuration handling

* feat(monitor-execution): streamline execution handling by integrating enqueuePendingExecution and removing unused mocks

* refactor(trading): remove workspace scoping from connection lookup

Co-authored-by: Codex <codex@openai.com>

* feat(tradinggoose): disable monitors on permanent dispatch failures

Co-authored-by: Codex <codex@openai.com>

* feat(monitor): refactor account resolution to include connectionOwnerUserId and streamline service ID handling

* feat(monitor-execution): enhance error handling for workflow backlog and update execution logic

* feat(indicator-monitor): update source identifier for monitor execution context

* feat(portfolio-monitor): generalize monitor management and add portfolio monitor features

* feat(monitor): remove TriggerExecutionUnavailableError mock from tests

* feat(portfolio-monitor): update condition labels and enhance async handling in data processing

---------

Co-authored-by: Codex <codex@openai.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 29, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
studio (staging) Ready Ready Preview, Comment May 30, 2026 2:13am

Request Review

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 29, 2026

Greptile Summary

This staging-to-main promotion merges three feature sets: a refreshed Records order table with provider order detail access, a Watchlist block and tool suite for workflow automation, and generalized monitor support expanding from indicator-only to source-aware indicator and portfolio monitors with condition evaluation, runtime dispatch, socket reconciliation, and workflow trigger integration.

  • Portfolio monitor runtime: New PortfolioMonitorRuntime subscribes to the portfolio manager's account-snapshot channel, evaluates fire conditions (edge vs. while_true, cooldown, crossing operators) against snapshots, enqueues monitor pending executions, and persists runtime state with optimistic concurrency. The indicator-monitor-runtime refactored to share the new monitor-runtime-lock helper and the widened AnyMarketProviderId type.
  • Monitor API consolidation: Old /api/indicator-monitors/* routes are replaced by source-aware /api/monitors/* routes that dispatch to indicator or portfolio config builders by source field; notifyMonitorsReconcile fires on create/update/delete.
  • Watchlist automation: New WatchlistBlock and four tool configs (readLists, readListItems, addListing, removeListing) use checkSessionOrInternalAuth to accept both session and workflow-internal requests; a new removeListingFromWatchlist operation resolves by ListingIdentity equality rather than item ID.

Confidence Score: 4/5

Safe to merge after addressing the pending-execution drain compatibility gap introduced by the executionType rename.

The executionType column value was renamed from 'indicator_monitor' to 'monitor' across the pending-execution stack. The drain's switch has no case for the old value, so any rows already in the table when workers are redeployed will hit default: throw, be logged but never completed, and re-enter the same failure loop every time the stale-processing window reclaims them. Indicator monitors fire on every market data tick, so in-flight rows are nearly certain at deploy time even in a coordinated rollout.

apps/tradinggoose/background/pending-execution-drain.ts and apps/tradinggoose/lib/execution/pending-execution.ts — the dropped 'indicator_monitor' case needs a backward-compat handler or a DB cleanup step before the new workers go live.

Important Files Changed

Filename Overview
apps/tradinggoose/background/pending-execution-drain.ts Renamed executionType case from 'indicator_monitor' to 'monitor' with no backward-compat path for pre-existing queued rows; orphaned rows will loop through claim → fail → stale-reclaim indefinitely.
apps/tradinggoose/lib/execution/pending-execution.ts Drops 'indicator_monitor' from PendingExecutionType and replaces it with 'monitor'; no migration path for existing queued rows of the old type.
apps/tradinggoose/app/api/monitors/route.ts New source-aware monitor create/list route generalizing from indicator-only to portfolio+indicator; auth, workspace permission, and reconcile-notify patterns look correct.
apps/tradinggoose/app/api/monitors/[id]/route.ts New GET/PATCH/DELETE route for unified monitors with proper workspace ownership checks and optimistic-concurrency on PATCH; runtimeState is preserved when the effective config doesn't change.
apps/tradinggoose/socket-server/trading/portfolio-monitor-runtime.ts New portfolio monitor runtime with shared lock helper, subscription lifecycle, edge/while_true fire modes, and optimistic-concurrency DB writes; non-firing state writes are now conditional on state transitions.
apps/tradinggoose/lib/monitors/portfolio-conditions.ts New portfolio condition evaluator with full metric set, operator compatibility guard, and ListingIdentity-backed position matching; crosses_above/crosses_below correctly return false when no previous snapshot exists.
apps/tradinggoose/background/monitor-execution.ts New dispatch shim that routes MonitorExecutionPayload to the correct handler by source; clean registry pattern.
apps/tradinggoose/blocks/blocks/watchlist.ts New Watchlist block with readLists/readListItems/addListing/removeListing operations; listing field correctly uses LISTING_IDENTITY_VALUE_TYPE and fetchOptions for removeListing is scoped to the selected watchlist.
apps/tradinggoose/tools/watchlist/index.ts New watchlist tool implementations; workspaceId is injected by the tool-execution framework for GET routes, POST mutations explicitly resolve it from _context.
apps/tradinggoose/app/api/watchlists/route.ts Adds checkSessionOrInternalAuth for workflow tool access, and a new watchlistId lookup path on GET to support the readListItems tool.
apps/tradinggoose/providers/trading/portfolio-identity.ts Renames tokenAccountId to credentialId in PortfolioIdentity, separating the public credential identifier from the internal OAuth token store key; getPortfolioIdentityKey updated consistently.
apps/tradinggoose/socket-server/trading/portfolio-manager.ts Refactored to support server-side onData/onError callbacks for monitor runtime subscriptions; now uses authorizeTradingConnectionRequest for credential resolution and adds workspace access checks.

Sequence Diagram

sequenceDiagram
    participant PM as PortfolioManager
    participant PMR as PortfolioMonitorRuntime
    participant DB as Database
    participant PE as PendingExecution queue
    participant Drain as pending-execution-drain
    participant WF as Workflow execution

    PMR->>DB: reconcile() SELECT active portfolio monitors
    DB-->>PMR: monitor rows
    PMR->>PM: subscribeData(portfolioIdentity, onData)

    loop every pollIntervalSeconds
        PM->>PM: poll trading provider
        PM->>PMR: onData(account-snapshot)
        PMR->>PMR: evaluatePortfolioFireCondition()
        alt condition fires
            PMR->>DB: getCurrentProviderConfig() SELECT
            PMR->>PE: "enqueuePendingExecution type=monitor"
            PMR->>DB: updateRuntimeState() SELECT+UPDATE
        else state transition only
            PMR->>DB: updateRuntimeState() SELECT+UPDATE
        else no change
            PMR->>PMR: update in-memory state only
        end
    end

    Drain->>PE: claimNextPendingExecution()
    PE-->>Drain: "row executionType=monitor"
    Drain->>Drain: isMonitorExecutionPayload()
    Drain->>WF: executePortfolioMonitorJob()
    WF-->>Drain: result
    Drain->>PE: completePendingExecution()
Loading

Fix All in Codex Fix All in Claude Code Fix All in Cursor

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
apps/tradinggoose/background/pending-execution-drain.ts:62-76
**Orphaned `indicator_monitor` rows after deployment**

`PendingExecutionType` dropped `'indicator_monitor'` and the drain's switch now handles only `'monitor'`. Any pending-execution row already in the DB with `executionType = 'indicator_monitor'` will hit the `default: throw` branch, be logged as an error, but never reach `completePendingExecution`. The row stays in its claimed state, is reclaimed after the 30-minute stale-processing window (`STALE_PROCESSING_WINDOW_MS`), and then fails in the same way on every subsequent drain invocation — creating an infinite failure loop for the entire lifetime of those rows.

Given that indicator monitors fire on every market data tick, there will almost certainly be in-flight `indicator_monitor` rows queued at the moment the workers are redeployed, even in a coordinated rollout. Adding a backward-compat case that immediately completes (or marks as failed) old-type rows would prevent this.

Reviews (3): Last reviewed commit: "fix(watchlist): fetch individual watchli..." | Re-trigger Greptile

…writes (#131)

* fix(monitor-runtime): refine runtime state update logic in PortfolioMonitorRuntime

* fix(portfolio-monitor): remove unused previousSnapshot schema and update runtime state handling

* fix(portfolio-monitor): update PortfolioMonitorProviderConfigSchema to use .strip() and .catch(undefined)
@TradingGoose-Dev
Copy link
Copy Markdown
Contributor Author

@greptileai

* feat(watchlist): add support for retrieving individual watchlists and update related tests

* fix(tests): update dynamic internal API URL to include filter and workspaceId
@TradingGoose-Dev
Copy link
Copy Markdown
Contributor Author

@greptileai

@TradingGoose-Dev TradingGoose-Dev merged commit f6a7da4 into main May 30, 2026
5 checks passed
@TradingGoose-Dev TradingGoose-Dev deleted the staging branch May 30, 2026 02:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants