Skip to content

UN-3741 [FIX] Show created/modified metadata on adapter and Prompt Studio list pages#2182

Merged
athul-rs merged 10 commits into
mainfrom
feat/un-3741-list-metadata
Jul 17, 2026
Merged

UN-3741 [FIX] Show created/modified metadata on adapter and Prompt Studio list pages#2182
athul-rs merged 10 commits into
mainfrom
feat/un-3741-list-metadata

Conversation

@athul-rs

@athul-rs athul-rs commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

What

  • Adapter list and Prompt Studio list rows now show an inline Updated <relative time> hint next to the owner, plus an info icon whose hover tooltip shows absolute Created / Modified times (browser timezone), the Model (adapters) and Prompt count (Prompt Studio).
  • Backend: AdapterListSerializer now returns created_at / modified_at; the Prompt Studio list returns modified_at as max(tool.modified_at, latest prompt.modified_at).
  • Owner email in list rows now ellipsizes with a full-address tooltip instead of wrapping mid-address when the row is tight.

Why

  • Customer request: richer metadata on the adapter and Prompt Studio list pages (created / modified times) to tell stale items from recently-touched ones.
  • Prompt edits never touch the CustomTool row, so exposing the raw modified_at would show misleadingly stale times on actively-edited projects — hence the latest-prompt subquery.

How

  • All display logic lives in the shared ListView widget (frontend/src/components/widgets/list-view/), which the adapter, Prompt Studio, Workflows and Connectors pages all render through. Rendering is presence-keyed on the item fields, so pages whose APIs lack a field simply don't show it.
  • No new endpoints and no extra frontend requests — everything rides the existing list responses. The Prompt Studio annotation is a correlated subquery in the same single list query, mirroring the existing _prompt_count subquery.

Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)

  • No. API changes are additive (two extra fields on the adapter list; Prompt Studio already returned modified_at, only its value becomes more accurate). The new UI block renders only when modified_at is present, so any consumer without the field renders exactly as before. Workflows and Connectors pages (same widget, serializers already return timestamps) gain the same display — verified to follow the same row anatomy.
  • Known nuance: the Prompt Studio tooltip's prompt count reuses the existing prompt_count field, which counts all prompt rows including notes (pre-existing semantics, also consumed elsewhere).

Database Migrations

  • None (uses existing BaseModel.created_at / modified_at columns).

Env Config

  • None.

Relevant Docs

  • N/A

Related Issues or PRs

Dependencies Versions

  • No changes (frontend reuses the existing moment dependency).

Notes on Testing

  • New test test_list_modified_at_reflects_prompt_edits (verified red on unpatched code, green with the fix); prompt studio suite 2/2 and adapter suite 22/22 against live Postgres.
  • ruff (pinned 0.3.4) clean, biome check clean, vite build clean.
  • Visual verification via the real ListView component rendered with representative data at standard width: rows stay single-line; long owner emails ellipsize with a full-address tooltip.

Screenshots

_Screenshots to
1

image

be attached below (list view + hover tooltips for adapters and Prompt Studio)._

Checklist

I have read and understood the Contribution Guidelines.

🤖 Generated with Claude Code

…tudio list pages

Adds an 'Updated <relative time>' hint plus an info icon with hover
tooltip (created at, last modified, model / prompt count when present)
to the shared ListView widget used by the adapter and Prompt Studio
list pages.

Backend: expose created_at/modified_at on AdapterListSerializer, and
surface the latest prompt modified_at on the Prompt Studio list —
prompt edits never touch the CustomTool row, so its own modified_at
understates activity.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adapter and Prompt Studio list APIs now expose creation and effective modification timestamps. The frontend list view renders update metadata, tooltips, action states, and constrained row layouts.

Changes

List metadata flow

Layer / File(s) Summary
Backend timestamp contracts and effective prompt updates
backend/prompt_studio/..., backend/adapter_processor_v2/serializers.py
List queries annotate the latest prompt modification, serializers return effective timestamps, adapter listings include creation and modification fields, and endpoint behavior is tested.
List metadata rendering
frontend/src/components/widgets/list-view/ListView.jsx
Rows display relative update times, metadata tooltips, truncated owner text, and deprecated-action states through dedicated rendering helpers.
Constrained list row styling
frontend/src/components/widgets/list-view/ListView.css
Row sizing, truncation, adapter wrapping, spacing, and modified metadata styles are updated.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ListView
  participant PromptStudioCoreView
  participant ToolStudioPrompt
  participant CustomToolListSerializer
  ListView->>PromptStudioCoreView: Request list data
  PromptStudioCoreView->>ToolStudioPrompt: Query latest prompt modified_at
  ToolStudioPrompt-->>PromptStudioCoreView: Return latest timestamp
  PromptStudioCoreView->>CustomToolListSerializer: Serialize effective metadata
  CustomToolListSerializer-->>ListView: Return created_at and modified_at
  ListView-->>ListView: Render updated time and metadata tooltip
Loading

Suggested reviewers: jaseemjaskp, ritwik-g

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and accurately summarizes the main change to list-page metadata.
Description check ✅ Passed The description follows the template and fills all required sections with relevant details.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/un-3741-list-metadata

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
frontend/src/components/widgets/list-view/ListView.jsx (1)

139-144: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make the metadata tooltip keyboard-accessible.

Ant Design's Tooltip relies on its child element being focusable to support keyboard navigation. Because Ant Design icons render as plain <span> elements by default, they do not receive keyboard focus unless explicitly instructed.

Consider adding tabIndex={0} to the icon so users navigating via keyboard can trigger and read the item metadata.

♿ Proposed accessibility fix
               <Tooltip title={renderItemMetadata(item)}>
                 <InfoCircleOutlined
+                  tabIndex={0}
                   className="adapters-list-info-icon"
                   aria-label="Creation and modification details"
                 />
               </Tooltip>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/components/widgets/list-view/ListView.jsx` around lines 139 -
144, Make the metadata Tooltip keyboard-accessible by adding tabIndex={0} to the
InfoCircleOutlined icon used as its child, preserving the existing tooltip
content and icon behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@backend/prompt_studio/prompt_studio_core_v2/tests/test_prompt_studio_author.py`:
- Line 104: Update the test setup around the CustomTool and ToolStudioPrompt
timestamp assertions to explicitly backdate the tool via its update operation,
bypassing auto_now and guaranteeing tool.modified_at is earlier than
prompt.modified_at. Keep the strict comparison and endpoint result assertion so
the test verifies the backend selects the prompt timestamp rather than relying
on coincidental row-creation timing.

---

Nitpick comments:
In `@frontend/src/components/widgets/list-view/ListView.jsx`:
- Around line 139-144: Make the metadata Tooltip keyboard-accessible by adding
tabIndex={0} to the InfoCircleOutlined icon used as its child, preserving the
existing tooltip content and icon behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fbba598d-3cd9-478a-909f-fdeb8bbd2d9b

📥 Commits

Reviewing files that changed from the base of the PR and between 94d78da and 0948d5b.

📒 Files selected for processing (6)
  • backend/adapter_processor_v2/serializers.py
  • backend/prompt_studio/prompt_studio_core_v2/serializers.py
  • backend/prompt_studio/prompt_studio_core_v2/tests/test_prompt_studio_author.py
  • backend/prompt_studio/prompt_studio_core_v2/views.py
  • frontend/src/components/widgets/list-view/ListView.css
  • frontend/src/components/widgets/list-view/ListView.jsx

Comment thread backend/prompt_studio/prompt_studio_core_v2/tests/test_prompt_studio_author.py Outdated
@greptile-apps

greptile-apps Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds "Updated " metadata and an info-icon tooltip (showing absolute Created/Modified times, Model, and Prompt count) to the Adapter and Prompt Studio list rows. The backend change is additive: AdapterListSerializer gains created_at/modified_at, and ToolStudioPrompt now bumps its parent CustomTool.modified_at on every save()/delete() so the plain field stays authoritative without a subquery.

  • Backend model hook: ToolStudioPrompt.save() and .delete() now call _touch_tool(), which issues a targeted CustomTool._base_manager.filter(pk=...).update(modified_at=now()) to propagate prompt activity to the parent row. sync_prompts adds an explicit bump to cover the queryset-delete path that bypasses instance methods.
  • sync_prompts deleted-count fix: the cascade total is now unpacked via per_model.get(ToolStudioPrompt._meta.label, 0) so only prompt rows are reported to the API client — a pre-existing accuracy bug fixed in this PR.
  • Frontend ListView refactor: the monolithic renderTitle helper is decomposed into renderTitle + renderMeta + renderActions; the layout switches from List.Item.Meta to a three-column Flexbox, gaining the showModified opt-in prop and ellipsis-with-tooltip for owner emails.

Confidence Score: 5/5

Safe to merge — all changes are additive on the API side and opt-in on the UI side; no migrations needed and no existing code paths are altered.

The backend changes are well-tested and carefully scoped: the _touch_tool() hook uses _base_manager to work outside request context, and sync_prompts explicitly covers the queryset-delete gap. The frontend refactor cleanly decomposes the list-row rendering and guards all new display elements behind showModified and field-presence checks.

No files require special attention. The N+1 UPDATE pattern in ToolStudioPrompt.save() during bulk imports is the only notable trade-off, and it is benign at current sync batch sizes.

Important Files Changed

Filename Overview
backend/adapter_processor_v2/serializers.py Adds created_at and modified_at to AdapterListSerializer.Meta.fields — minimal, additive change.
backend/adapter_processor_v2/tests/test_adapter_api.py New test pins that list responses include timestamps and a rename advances modified_at while created_at remains stable; uses backdate+update() to avoid wall-clock dependency.
backend/prompt_studio/prompt_studio_v2/models.py Adds _touch_tool() / save() / delete() overrides to ToolStudioPrompt; each prompt write now fires an extra UPDATE to CustomTool. Bulk queryset writes (update/bulk_create) still bypass the hook — acknowledged in comments.
backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py Fixes sync_prompts to explicitly bump CustomTool.modified_at when the queryset delete removes rows (bypasses _touch_tool()), and correctly extracts only the prompt-row count from the cascade delete result.
backend/prompt_studio/prompt_studio_core_v2/views.py Removes the correlated modified_at subquery (no longer needed since parent row is bumped at source); adds a comment warning that future write paths must bump CustomTool themselves.
backend/prompt_studio/prompt_studio_core_v2/tests/test_prompt_studio_author.py Adds five integration tests covering prompt-write bump, isolation between tools, sync-clear bump, org-context-free bump, and list-endpoint consistency. All use explicit backdate to avoid wall-clock fragility.
frontend/src/components/widgets/list-view/ListView.jsx Decomposes the list-row rendering into renderTitle, renderMeta, and renderActions; adds showModified prop, owner email ellipsis, and info-icon tooltip via renderItemMetadata.
frontend/src/helpers/GetStaticData.js New timeAgo() helper: strict ISO 8601 parsing returns "" for invalid input; clamps to now via moment.min to suppress "in a few seconds" from a fast server clock.
frontend/src/components/widgets/list-view/ListView.css Replaces fixed-width column layout with three-column Flexbox; adds .list-view-modified-container and .list-view-info-icon styles.
frontend/src/components/custom-tools/list-of-tools/ListOfTools.jsx Edit-item update now merges PATCH response over existing item ({...item, ...data}) so list-only fields like prompt_count aren't dropped; adds showModified to the list view.
frontend/src/components/custom-tools/view-tools/ViewTools.jsx Pass-through of new showModified prop to ListView; PropTypes updated accordingly.
frontend/src/components/tool-settings/tool-settings/ToolSettings.jsx Enables the new showModified display on the Adapter list by passing the prop to ViewTools.

Reviews (11): Last reviewed commit: "UN-3741 [MISC] Make code comments concis..." | Re-trigger Greptile

Comment thread backend/prompt_studio/prompt_studio_core_v2/tests/test_prompt_studio_author.py Outdated
@athul-rs
athul-rs requested review from jaseemjaskp and ritwik-g July 17, 2026 03:20
Restructure ListView rows into three vertically-centered columns
(title+description, owner+updated, actions) so the metadata cluster
centers against the whole entry instead of hugging the title line.
Consistent flex gaps replace the old width-percentage layout; row
padding bumped for breathing room.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/components/widgets/list-view/ListView.jsx`:
- Around line 121-126: Update the created-by display expression in ListView to
access the current session email safely when comparing against
item.created_by_email. Use optional chaining on sessionDetails while preserving
the existing “Me”, email, and “-” display behavior.
- Around line 156-184: Update the EditOutlined and ShareAltOutlined onClick
handlers in the list item action rendering to ignore clicks when
item?.is_deprecated is true, while preserving the existing handleEdit and
handleShareClick behavior for active items.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 788871d5-2ed0-4361-98f3-5716c21da620

📥 Commits

Reviewing files that changed from the base of the PR and between 0948d5b and 8b19617.

📒 Files selected for processing (2)
  • frontend/src/components/widgets/list-view/ListView.css
  • frontend/src/components/widgets/list-view/ListView.jsx

Comment thread frontend/src/components/widgets/list-view/ListView.jsx Outdated
Comment thread frontend/src/components/widgets/list-view/ListView.jsx
Full text remains available via the ellipsis tooltip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@athul-rs
athul-rs force-pushed the feat/un-3741-list-metadata branch from ec32691 to 2be21c9 Compare July 17, 2026 07:54
Reconciles UN-2202 co-owner changes with the UN-3741 list metadata:
renderOwnerBadge (membership model, +N co-owners) grafted into the
restructured three-column row; serializer keeps both field sets. List
test now creates the project via the API so ownership membership rows
exist under the new visibility model.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@athul-rs athul-rs changed the title UN-3741 [FEAT] Show created/modified metadata on adapter and Prompt Studio list pages UN-3741 [FIX] Show created/modified metadata on adapter and Prompt Studio list pages Jul 17, 2026
…recated actions

- Pin the prompt's modified_at to a known future instant in the list
  test so back-to-back creates can't tie on coarse clocks (Greptile P2)
- Block edit/share click handlers on deprecated items to match their
  disabled styling (CodeRabbit)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@ritwik-g ritwik-g left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — UN-3741 list metadata (no P1s; 3 P2, 3 P3 inline)

Severity: P1 must fix / P2 should fix / P3 optional. Every P2 was independently verified against the code (details in each inline comment).

Checked and cleared:

  • Backend annotation/serializer pairing is sound: CustomToolListSerializer is only returned for the list action, and get_queryset always annotates _last_prompt_modified for it; the datetime comparison is tz-aware-safe; a SerializerMethodField shadowing a Meta.fields model field is valid DRF.
  • All four ListView consumers (adapters, Prompt Studio, Workflows, Connectors) get both timestamps from their list serializers — no page silently loses the new meta column. The removed CSS classes (list-view-content, adapters-list-title-container, list-item-desc) have no other references.
  • moment(...) / formattedDateTime parse DRF's ISO-8601 output cleanly (no DATETIME_FORMAT override, USE_TZ=True) — no "Invalid date" path.
  • Prompt reorders / bulk ops do bump modified_at: BaseModelQuerySet patches update()/bulk_update() (utils/models/base_model.py:40-54) and ToolStudioPrompt inherits that manager — so the "honest last modified" holds for those paths too.
  • No existing tests were modified or deleted; the new test genuinely exercises the list-action → annotation → serializer path and fails without the fix.
  • CodeRabbit's "critical" sessionDetails render-crash is a false positive — ListView.jsx:85 already uses sessionDetails?.email and this PR doesn't touch that line. The deprecated-icon onClick behavior it flagged as major is pre-existing code moved verbatim, out of this PR's scope.

P3 (not inline): title type — this is customer-requested new metadata display, arguably [FEAT] rather than [FIX] per the release-notes standard; author's call since it also corrects the misleadingly stale modified_at.

Comment thread backend/prompt_studio/prompt_studio_core_v2/serializers.py Outdated
Comment thread backend/prompt_studio/prompt_studio_core_v2/serializers.py Outdated
Comment thread frontend/src/components/widgets/list-view/ListView.jsx Outdated
Comment thread frontend/src/components/widgets/list-view/ListView.jsx Outdated
Comment thread backend/prompt_studio/prompt_studio_core_v2/tests/test_prompt_studio_author.py Outdated
Comment thread frontend/src/components/widgets/list-view/ListView.css Outdated
ritwik-g
ritwik-g previously approved these changes Jul 17, 2026

@ritwik-g ritwik-g left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues — zero P1s. The three P2s in my review (silently-ignored ?ordering=modified_at, silent stale fallback in get_modified_at, dead centered prop) are latent/hardening/cosmetic and fine as a follow-up. Backend annotation path, all four ListView consumers, and the new test were verified against the PR head.

@ritwik-g
ritwik-g dismissed their stale review July 17, 2026 09:39

Checking some points closely.

@ritwik-g ritwik-g left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-approving after re-examining the ordering finding: pre-PR, ?ordering=modified_at only worked for org admins (regular users 500'd on the distinct("tool_id") queryset) and no client sends it — confirmed non-blocking, details in the thread on serializers.py:49. All other findings remain follow-up material (no P1s).

@jaseemjaskp jaseemjaskp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review Toolkit — Code Reviewer, Silent Failure Hunter, Type Design Analyzer, PR Test Analyzer, Comment Analyzer and Code Simplifier. 14 findings below; items already raised by other reviewers are excluded.

The feature is well-motivated and the latest-prompt subquery is the right instinct — the _prompt_count mirroring is clean, the UN-2202 comment in the test documents a genuine trap, and the removed CSS classes were verified unreferenced. Three findings are blocking.

Blocking

  1. ListView.jsx:176 — the "Updated" block is presence-keyed, so it silently ships to Workflows and Connectors. Both serializers are fields = "__all__" over BaseModel, so both pages gain the label with no backend change and no test. On Workflows the value is structurally stale in exactly the way this PR fixes for Prompt Studio (content lives in ToolInstance/WorkflowEndpoint, which never write the Workflow row) — a user reconfigures endpoints today and reads "Updated 8 months ago". On Connectors it's bumped by automatic OAuth token refresh (connector_auth_v2/models.py:114), so "Updated 2 minutes ago" appears on connectors nobody touched. Presence of a field isn't evidence of its meaning — make the opt-in explicit.

  2. views.py:173 — the derived timestamp travels backwards on prompt delete. ToolStudioPrompt has no save/delete override and no signals, so deleting the newest prompt drops the tool's reported modified_at to the next-newest. The user performs an edit and the row ages by three days.

  3. serializers.py:74modified_at means two different things on two endpoints. list returns the derived max; every other action goes through CustomToolSerializer (fields = "__all__") and returns the raw row. List then GET makes the timestamp jump backwards, with nothing on the wire to distinguish them.

One fix collapses all three, plus the ?ordering=modified_at breakage already reported: bump the parent row at the source (post_save/post_delete on ToolStudioPromptCustomTool.objects.filter(pk=...).update(modified_at=now())). modified_at becomes honest for creates, edits and deletes; both serializers agree because there's only one value; ordering works because it's a real column again; and the annotation, the SerializerMethodField and the view↔serializer coupling all disappear. If you'd rather keep deriving, computing the max in SQL via Greatest/Coalesce restores sortability — but note it does not fix the delete case (#2).

Low — a dead click strip through the middle of every row (ListView.jsx:170); the title doesn't ellipsize despite the comment, so long titles wrap and break row uniformity (ListView.css:59); the adapter fields ship with zero coverage of the list endpoint (adapter_processor_v2/serializers.py:173); the new test's single-tool/single-prompt fixture can't detect a lost OuterRef correlation or a flipped sort (test_prompt_studio_author.py:106).

Nits — dead showOwner guard, mixed presence conventions, eagerly-built tooltip, unguarded "Invalid date" rendering, moment/dayjs split, adapters-list-* prefix on generic classes, and a misleading min-width: 0 comment.

Also worth folding into the centered cleanup already raised: ListView.css:40-46 still targets .ant-list-item-meta, which no longer renders anywhere now that List.Item.Meta is gone — both rules are unreachable. (Outside the diff, so no inline comment.)

Comment thread frontend/src/components/widgets/list-view/ListView.jsx Outdated
Comment thread backend/prompt_studio/prompt_studio_core_v2/views.py Outdated
Comment thread backend/prompt_studio/prompt_studio_core_v2/serializers.py Outdated
Comment thread frontend/src/components/widgets/list-view/ListView.jsx Outdated
Comment thread frontend/src/components/widgets/list-view/ListView.css
Comment thread frontend/src/components/widgets/list-view/ListView.jsx Outdated
Comment thread frontend/src/components/widgets/list-view/ListView.jsx Outdated
Comment thread frontend/src/components/widgets/list-view/ListView.jsx Outdated
Comment thread frontend/src/components/widgets/list-view/ListView.css Outdated
Comment thread frontend/src/components/widgets/list-view/ListView.css Outdated
… Updated label

Backend — maintain modified_at at the source instead of deriving it
(review: derived max could travel backwards on prompt delete, and gave
the same field two meanings across list/detail while breaking
?ordering=modified_at):
- ToolStudioPrompt.save()/delete() now bump the parent CustomTool row;
  the list subquery annotation and SerializerMethodField are gone, so
  the plain field is honest, identical on every endpoint, and orderable
- Tests pin create/edit/delete bumps, cross-tool isolation, and the
  promptless-project case; adapter list endpoint gains coverage
  (timestamps present, rename bumps modified_at, created_at stable)

Frontend — the Updated label is now explicit opt-in (showModified),
passed only by the adapter and Prompt Studio lists; Workflows and
Connectors no longer inherit a misleading value by field presence:
- New timeAgo helper (strict ISO parse, clamped to now) replaces raw
  moment usage: malformed input hides the label instead of rendering
  "Invalid date"
- Meta column no longer swallows row clicks; titles ellipsize like
  descriptions; tooltip fields use one presence convention (!= null)
  and build lazily; centered prop wired into the row Flex (dead CSS
  removed); updateList merges PATCH responses so list-only fields
  survive edits; new CSS classes renamed to the widget's list-view-*
  prefix; two misleading CSS comments corrected

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread backend/prompt_studio/prompt_studio_v2/models.py
@athul-rs
athul-rs requested a review from jaseemjaskp July 17, 2026 10:45
…asses model delete

sync_prompts clears existing prompts with a queryset delete, which never
calls ToolStudioPrompt.delete() — so a prompts-clearing sync with no
tool-settings payload left the parent's modified_at stale, violating the
invariant the parent-bump establishes (Greptile). The sync now bumps the
tool explicitly when rows were deleted; pinned by a test that runs a
clearing sync and asserts the bump.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@jaseemjaskp jaseemjaskp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Second pass. The parent-bump-at-source redesign is the right call and the backend tests are genuinely good — test_prompt_bump_only_touches_its_own_tool is the one most people omit, and it's the one that would catch a _touch_tool that lost its pk filter. Three findings that clear the bar; the rest of what I checked came back clean (details below).

Verified clean, so nobody re-treads them: reorder does bump (the bulk_update at prompt_studio_v2/helper.py:112 looks like a bypass, but reorder_prompts_helper finishes with prompt_instance.save() at helper.py:64); import_prompts uses objects.create() so the sync ADD path bumps via save(); the deleted CSS classes (.list-view-content, .adapters-list-title-container, .list-item-desc) have zero references left repo-wide; centered is still live and correctly rewired to the row Flex align; AdapterListSerializer leaks nothing (secrets live in adapter_metadata_b, never in that tuple), and the detail serializer already exposed both fields via fields = "__all__", so list is now a strict subset. No deadlock risk on the N-prompt import loop either — I looked for an inverted lock order and there isn't one.

Comment thread backend/prompt_studio/prompt_studio_v2/models.py Outdated
Comment thread backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py
Comment thread backend/prompt_studio/prompt_studio_core_v2/views.py Outdated
…unt, scoped claim

- _touch_tool and the sync bump now use CustomTool._base_manager: the
  org-scoped default manager reads a thread-local and would silently
  match zero rows outside request context; delete() collapsed onto
  _touch_tool (the FK attname survives super().delete()) so the two
  paths can't drift
- sync_prompts reports the per-model prompt count, not the cascade
  total that dragged PromptStudioOutputManager rows into
  "prompts_deleted"; the sync test fixture now carries an output row so
  the assertion discriminates
- List-queryset comment scopes the invariant honestly: only prompt
  writes bump; ProfileManager/DocumentManager and queryset-level prompt
  writes are tracked as UN-3759

Review: PR #2182 round 3 (Jaseem)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chandrasekharan-zipstack chandrasekharan-zipstack left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider making code comments concise and generic and removing the JIRA dependency if its not truly required

@athul-rs
athul-rs requested a review from jaseemjaskp July 17, 2026 11:42
Ticket references belong in commits and PRs, not code — they mean
nothing to OSS contributors. Comments and test docstrings now state the
behavior generically; the ProfileManager/DocumentManager bump gap stays
documented in the list-queryset comment without the tracker pointer.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Frontend Lint Report (Biome)

All checks passed! No linting or formatting issues found.

@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown
Contributor

Unstract test results

Per-group results

Status Group Tier Passed Failed Errors Skipped Duration (s)
e2e-coowners e2e 1 0 0 0 1.3
e2e-login e2e 2 0 0 0 1.4
e2e-smoke e2e 2 0 0 0 1.3
integration-backend integration 124 0 0 27 68.4
integration-connectors integration 1 0 0 7 8.3
unit-backend unit 151 0 0 0 21.7
unit-connectors unit 63 0 0 0 9.8
unit-core unit 27 0 0 0 1.3
unit-platform-service unit 15 0 0 0 2.6
unit-rig unit 71 0 0 0 4.3
unit-sdk1 unit 435 0 0 0 25.5
unit-workers unit 723 0 0 0 47.9
TOTAL 1615 0 0 34 193.7

Critical paths

⚠️ Critical paths not yet covered

  • workflow-create-execute — Create a workflow, configure source+destination, execute, poll, fetch result. (declared coverage: e2e-workflow)
  • api-deployment-run — Deploy a workflow as an API, POST a document, receive structured JSON. (declared coverage: e2e-api-deployment)
  • prompt-studio-fetch-response — Prompt Studio: create project, add prompt, run single-pass, get response. (declared coverage: e2e-prompt-studio)
  • pipeline-etl-execute — Run an ETL pipeline from source connector to destination. (declared coverage: no groups declared)
  • usage-token-tracking — Per-execution token usage is recorded and retrievable. (declared coverage: no groups declared)
  • workflow-execution-fan-out — Multi-file workflow execution fans out to file-processing workers and rejoins. (declared coverage: no groups declared)
  • callback-result-delivery — Async results are posted back via the callback worker. (declared coverage: no groups declared)
✅ Covered critical paths
  • auth-login — covered by e2e-login
  • adapter-register-llm — covered by integration-backend
  • workflow-author — covered by integration-backend
  • co-owner-manage — covered by integration-backend, e2e-coowners
  • api-deployment-provision — covered by integration-backend
  • api-deployment-auth — covered by integration-backend
  • prompt-studio-author — covered by integration-backend
  • connector-register-test — covered by integration-backend
  • usage-aggregate-read — covered by integration-backend

@jaseemjaskp jaseemjaskp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Six-agent PR Review Toolkit pass (code review, silent-failure, type design, tests, comments, simplification) over the backend bump logic and the ListView refactor. No blocking findings — approving.

I verified the load-bearing claims independently rather than trusting them:

  • Deletion collector — Django 4.2.30 deletion.py nulls only model._meta.pk.attname (lines 456, 519-521); tool_id_id survives super().delete(), so the delete-bump works. Comment is accurate.
  • _base_manager / org scopeCustomToolModelManager mixes in DefaultOrganizationManagerMixin (thread-local scoped); no base_manager_name anywhere in the MRO, so _base_manager is a plain unfiltered Manager. tool_id is a UUID pk. All three sub-claims hold, and test_prompt_bump_survives_missing_org_context genuinely pins it.
  • Prompt reorder — flagged by one agent as bypassing the bump via bulk_update; that is wrong. reorder_prompts_helper ends in prompt_instance.save() (prompt_studio_v2/helper.py:64), which fires _touch_tool(). Reorder does bump.
  • per_model.get(ToolStudioPrompt._meta.label, 0)Collector.delete() keys by _meta.label; the 0 default is only hit at zero rows. Correct, and the sync test builds a real CASCADE fixture so the assertion actually discriminates 1 from 2.
  • Backdating helper — works only because BaseModelQuerySet.update uses setdefault; had it been an unconditional assign, every > assertion would be vacuous. It is not. Tests are honest.
  • CSS.list-view-content, .adapters-list-title-container, .list-item-desc have zero remaining references; centered is still honored via the new Flex align.

Non-blocking notes, no action needed for this PR:

  1. views.py:971 (.update(profile_manager=...) on first-profile creation) bypasses the bump, leaving a stale label on that one path. Pre-existing, display-only, self-healing on the next prompt edit, and the views.py:167-171 comment already warns about this class.
  2. Source-bumping is prospective only — existing projects keep their current modified_at until the next prompt write. Worth a thought, but the field never included prompt activity before, so this is strictly an improvement.
  3. sync_prompts fires N+2 writes to one CustomTool row per sync. Real write amplification, but prompts-per-tool is in the tens and sync is infrequent — not a throughput concern.
  4. timeAgo() is untested and the harness exists (vitest, sibling helpers/requestId.test.js). The strict-parse and moment.min clamp are exactly the non-obvious bits a future cleanup would strip. Cheap to add whenever.

One thing worth fixing outside the diff: the PR description is stale. It still says the Prompt Studio list returns modified_at as max(tool.modified_at, latest prompt.modified_at) via a correlated subquery, and cites a test test_list_modified_at_reflects_prompt_edits that no longer exists. The implementation moved to source-bumping. Worth updating before merge so the description matches what ships.

@athul-rs
athul-rs merged commit 714b903 into main Jul 17, 2026
12 checks passed
@athul-rs
athul-rs deleted the feat/un-3741-list-metadata branch July 17, 2026 12:01
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.

4 participants