Skip to content

TT 7363 pending restore - #544

Draft
gtryus wants to merge 3 commits into
developfrom
TT-7363-pending-restore
Draft

TT 7363 pending restore#544
gtryus wants to merge 3 commits into
developfrom
TT-7363-pending-restore

Conversation

@gtryus

@gtryus gtryus commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

QA: vernacular/PBT retry places the file; speaker info, audio comment/translation do not; title often never appears in the pending list.

Likely split inside this PR (still one PR; sequential tests)

  1. Title pending not created — often fixed by PR 1 enqueue-on-stage if Title save already goes through nextUpload. First test: Title/useMediaUpload terminal failure (or staged upload) appends pending with artifactTypeId = title. If Title still bypasses staging, fix that path only.
  2. Speaker list empty after retry — SpeakerName.tsx lists intellectualproperty + releaseMediafile transcription, not bare mediafiles. Extract createIntellectualPropertyForMedia from ProvideRights.tsx afterUploadCb (rightsHolder, notes/statement, org, media id). On pending retry success, if snapshot is IP (ArtifactTypeSlug.IntellectualProperty), call it.
  • Snapshot today may lack transcription (ProvideRights writes it after upload). Extend PendingUploadRecord with optional sideEffects: { rightsHolder, statement, organizationId } filled at enqueue from MediaRecord/performedBy + ProvideRights statement before nextUpload.
  1. Comment / translation “wrong location” — verify the pending snapshot’s artifactTypeId, passageId, sourceMediaId, sourceSegments are posted by toVnd on retry (unit test on the snapshot, not the full UI). If comments still need saveComment(discussionId, commentId, mediaId), add those ids to sideEffects at enqueue in CommentCard.tsx / PassageDetailItem.tsx.

Red-green slices

  1. Helper: IP artifact pending + sideEffects.rightsHolder → memory.update creates intellectualproperty linked to releaseMediafile and organization (mock Orbit AddRecord / ReplaceRelatedRecord like other CRUD tests).
  2. Dialog/retry orchestration test: after successful retry of an IP pending row, the helper is invoked with the new stringId (mock nextUpload cb).
  3. Comment: retry POST relationships include artifact-type and source-media from the snapshot; if that is insufficient, a second test that saveComment is called when sideEffects.discussionId is present.
  4. Title: staged/failed title upload appears in loadPendingMediaUploads().

Keep ProvideRights production behavior for the in-step save; retry is the new caller of the extracted helper.

QA: vernacular/PBT retry places the file; speaker info, audio comment/translation do not; title often never appears in the pending list.

Likely split inside this PR (still one PR; sequential tests)
1. Title pending not created — often fixed by PR 1 enqueue-on-stage if Title save already goes through nextUpload. First test: Title/useMediaUpload terminal failure (or staged upload) appends pending with artifactTypeId = title. If Title still bypasses staging, fix that path only.
2. Speaker list empty after retry — SpeakerName.tsx lists intellectualproperty + releaseMediafile transcription, not bare mediafiles. Extract createIntellectualPropertyForMedia from ProvideRights.tsx afterUploadCb (rightsHolder, notes/statement, org, media id). On pending retry success, if snapshot is IP (ArtifactTypeSlug.IntellectualProperty), call it.
- Snapshot today may lack transcription (ProvideRights writes it after upload). Extend PendingUploadRecord with optional sideEffects: { rightsHolder, statement, organizationId } filled at enqueue from MediaRecord/performedBy + ProvideRights statement before nextUpload.
3. Comment / translation “wrong location” — verify the pending snapshot’s artifactTypeId, passageId, sourceMediaId, sourceSegments are posted by toVnd on retry (unit test on the snapshot, not the full UI). If comments still need saveComment(discussionId, commentId, mediaId), add those ids to sideEffects at enqueue in CommentCard.tsx / PassageDetailItem.tsx.

### Red-green slices
1. Helper: IP artifact pending + sideEffects.rightsHolder → memory.update creates intellectualproperty linked to releaseMediafile and organization (mock Orbit AddRecord / ReplaceRelatedRecord like other CRUD tests).
2. Dialog/retry orchestration test: after successful retry of an IP pending row, the helper is invoked with the new stringId (mock nextUpload cb).
3. Comment: retry POST relationships include artifact-type and source-media from the snapshot; if that is insufficient, a second test that saveComment is called when sideEffects.discussionId is present.
4. Title: staged/failed title upload appears in loadPendingMediaUploads().

Keep ProvideRights production behavior for the in-step save; retry is the new caller of the extracted helper.
@gtryus
gtryus marked this pull request as draft August 25, 2026 21:54
…sibility states

-Comment retry drops approval and visibility
- IP retry writes speaker name as transcription

Copilot AI 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.

Pull request overview

This PR addresses TT-7363 pending-upload retry gaps in the renderer upload flow by capturing additional “side effects” at enqueue time (IP metadata, comment metadata) and replaying them after a successful retry so the restored media is re-linked correctly in Orbit.

Changes:

  • Added PendingUploadSideEffects to persist IP/comment metadata alongside pending upload queue entries and plumbed it through UploaderuseMediaUploadnextUpload.
  • Introduced restorePendingUploadSideEffects to replay IP creation/transcription and comment attachment after a pending retry succeeds (invoked from PendingUploadsDialog).
  • Extracted shared IP creation logic into createIntellectualPropertyForMedia, reused by both ProvideRights and the retry side-effect restoration path, with added unit tests.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/renderer/src/store/upload/restorePendingUploadSideEffects.ts New helper to replay IP/comment-related side effects after a successful retry.
src/renderer/src/store/upload/restorePendingUploadSideEffects.test.ts Unit tests for restoring IP creation behavior and comment attachment behavior.
src/renderer/src/store/upload/pendingMediaUploads.ts Adds PendingUploadSideEffects and stores it in pending upload records.
src/renderer/src/store/upload/pendingMediaUploads.test.ts Verifies sideEffects persistence when appending pending uploads.
src/renderer/src/store/upload/actions.tsx Extends nextUpload props to capture pendingSideEffects and include them in queued records on stage/failure.
src/renderer/src/store/upload/actions.pendingRetry.test.ts Ensures pendingSideEffects are stored on staged queue rows.
src/renderer/src/crud/useMediaUpload.ts Adds optional pendingSideEffects (value or thunk) and passes it through to nextUpload.
src/renderer/src/crud/index.ts Re-exports createIntellectualPropertyForMedia.
src/renderer/src/crud/createIntellectualPropertyForMedia.ts New CRUD helper to create IP linked to release media + organization and optionally apply transcription.
src/renderer/src/crud/createIntellectualPropertyForMedia.test.ts Unit tests for IP creation transforms and optional transcription application.
src/renderer/src/components/Uploader.tsx Accepts and forwards pendingSideEffects into upload dispatch for queue persistence.
src/renderer/src/components/Team/PendingUploadsDialog.tsx On retry success, pulls the mediafile and replays saved side effects (IP/comment) for the retried entry.
src/renderer/src/components/ProvideRights.tsx Uses the extracted IP helper and supplies IP pendingSideEffects at enqueue time.
src/renderer/src/components/MediaRecord.tsx Threads pendingSideEffects through to useMediaUpload.
src/renderer/src/components/Discussions/ReplyCard.tsx Captures comment side effects at enqueue time for retry re-attachment.
src/renderer/src/components/Discussions/DiscussionCard.tsx Captures comment side effects at enqueue time for retry re-attachment.
src/renderer/src/components/Discussions/CommentEditor.tsx Threads pendingSideEffects into the recording/upload component.
src/renderer/src/components/Discussions/CommentCard.tsx Captures edit-time approval/visibility + IDs into side effects so retry can preserve them.
Suppressed comments (3)

src/renderer/src/store/upload/actions.tsx:47

  • PendingUploadSideEffects is only used as a type in NextUploadProps; import it as a type-only named import to avoid emitting a runtime import.
import {
  appendPendingMediaUpload,
  PendingUploadRecord,
  PendingUploadMediaRecord,
  PendingUploadSideEffects,
  removeMatchingPendingUploads,
  removePendingMediaUpload,
  updatePendingMediaUpload,
} from './pendingMediaUploads';

src/renderer/src/crud/createIntellectualPropertyForMedia.ts:6

  • These Orbit record symbols are only used for typing/casts here; import them with import type to avoid runtime imports.
import {
  RecordIdentity,
  RecordKeyMap,
  UninitializedRecord,
} from '@orbit/records';

src/renderer/src/crud/createIntellectualPropertyForMedia.ts:8

  • IntellectualProperty and MediaFileD are only used in type assertions; use type-only imports to avoid emitting runtime imports.
import IntellectualProperty from '../model/intellectualProperty';
import { MediaFileD } from '../model';

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

import { getContentType } from '../utils/contentType';
import { OrbitNetworkErrorRetries } from '../../api-variable';
import { formatUploadTerminalFailureMessage } from '../store/upload/uploadTerminalMessages';
import { PendingUploadSideEffects } from '../store/upload/pendingMediaUploads';
Comment on lines +1 to +2
import Memory from '@orbit/memory';
import { MediaFileD } from '../../model';
Comment on lines 156 to +169
await pullTableList(
'mediafile',
[sid],
memory,
remote,
backup,
reporter
);
await restorePendingUploadSideEffects({
entry,
mediaId: sid,
memory,
user,
organizationId: organization,
@@ -0,0 +1,70 @@
import Memory from '@orbit/memory';
…omponents

- Recorded speaker rights not restored on retry
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