Skip to content

feat(frontend): actress-frontend-sync (phase 6/6) - #213

Merged
seeyabye merged 3 commits into
integ/actress-sync-p12from
feat/actress-frontend-sync
Aug 15, 2026
Merged

seeyabye merged 3 commits into
integ/actress-sync-p12from
feat/actress-frontend-sync

Conversation

@seeyabye

Copy link
Copy Markdown
Contributor

Phase 6 of 6: frontend sync modal, filter toolbar, cross-page selection, settings resolver-priority UI, setup wizard, manual/review/browse sanitize paths, and full i18n. Sub-PR targeting the #209 epic branch.

@seeyabye

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review


P1 Badge Scope placeholder data to the requested review job

When navigating directly from /review/A to /review/B, TanStack Query can supply job A as placeholder data while B is loading; the synchronization effect accepts that placeholder and the page remains actionable. A user acting during this window can therefore submit A's result IDs or edits through API calls scoped to job B, causing failures or modifying an overlapping result in the wrong job. Retain the previous id === jobId guard or ignore mismatched placeholder data.


const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'actresses.json';

P1 Badge Route actress exports through the desktop save helper

In the Wails desktop app, anchor-based downloads are silently discarded by the webview, so this path reports a successful export without creating a file. The removed saveJsonFile helper explicitly routes desktop exports through /desktop/save-file and a native save dialog; actress exports need to keep using that helper.


updateCurrentMovie({
...currentMovie,
cropped_poster_url: original.cropped_poster_url,
should_crop_poster: original.should_crop_poster,
});

P2 Badge Clear manual crop geometry when resetting the poster

When a manual crop changes only the cropped poster while the underlying poster_url still matches the scraped baseline, Reset takes this branch but preserves poster_crop_bounds. Saving then sends the old bounds back, and the backend's PATCH semantics retain/reapply that crop, so the supposedly reset poster can be cropped again during output. Reset must explicitly set the bounds to null (and synchronize multipart overlays).


editingPriority = [...getFieldPriority(config, fieldKey)];

P2 Badge Exclude actress-only resolvers when opening movie fields

If the global priority contains an actress-only resolver, opening a non-actress field derives an editing list that still contains it. Reordering that field and saving creates an explicit movie-field override containing the resolver, which the backend's capability validator rejects; filtering only the add chips does not prevent this path. Apply filterFieldEligibleScrapers when initializing non-actress editors as well.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@seeyabye

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

preset: isUpdateMode ? (selectedPreset as 'conservative' | 'gap-fill' | 'aggressive' | undefined) : undefined,
scalar_strategy: isUpdateMode ? scalarStrategy : undefined,
array_strategy: isUpdateMode ? arrayStrategy : undefined,
operation_mode: effectiveOperationMode,

P1 Badge Restore canonical apply-plan submission

For every scrape launched from Browse, this request now sends only the legacy operation and merge fields and never includes apply_plan. The same change removes the operation-plan UI and its validation, so users can no longer select or submit canonical NFO and media policies such as skipping NFO, replacing existing media, or metadata/artwork-only behavior; jobs silently fall back to legacy defaults instead. Restore the plan construction and include the normalized plan in this request.


if (data) {
job = JSON.parse(JSON.stringify(data));
} else if (isPending && !isPlaceholder) {

P1 Badge Reject placeholder jobs from the previous route

When client-side navigation changes /review/A to /review/B, TanStack Query supplies job A through placeholderData while B is loading, but this effect now copies that placeholder into job without checking data.id === jobId. Because loading also no longer checks the ID, the review page temporarily exposes A's movies and actions under B's route; an immediate edit or organize action can consequently combine B's job ID with A's result data. Keep the previous ID guard or avoid cross-job placeholder data.



P2 Badge Remove the generated dependency backup

Do not commit this dependency tree: node_modules_bak contains about 16,300 generated files totaling roughly 172 MB. Its renamed directory bypasses the existing node_modules/ ignore rules, and the Dockerfile's COPY web/frontend/ ./ includes it in the frontend build stage, substantially inflating every clone, checkout, Docker context, and source-copy layer without contributing application code.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@seeyabye

Copy link
Copy Markdown
Contributor Author

@codex review this frontend phase

@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

selected_scrapers: showScraperSelector ? selectedScrapers : undefined,
preset: isUpdateMode ? (selectedPreset as 'conservative' | 'gap-fill' | 'aggressive' | undefined) : undefined,
scalar_strategy: isUpdateMode ? scalarStrategy : undefined,
array_strategy: isUpdateMode ? arrayStrategy : undefined,
operation_mode: effectiveOperationMode,

P1 Badge Restore the canonical apply plan in batch requests

For every scrape started directly from Browse, this request now omits apply_plan and sends only the legacy mirrors. Consequently the backend treats the job as a legacy job and cannot preserve the selected NFO output, media download/replacement policy, or canonical merge intent through Review; existing saved phase-2 plans are also discarded during hydration. This can make a scrape write or download assets according to configuration defaults instead of the user's operation plan.


async function organizeAll() {
await organizeController.organizeAll(skipNfo, skipDownload);

P1 Badge Forward Review apply overrides when organizing

When the user changes Review controls such as Force overwrite, Preserve NFO, Replace existing media, or the merge preset and then runs an organize operation, this call supplies only skipNfo and skipDownload. organize-controller.ts therefore sends overrides: undefined, so those visible controls are silently ignored and the backend applies the job/default policy instead.


const a = document.createElement('a');
a.href = url;
a.download = 'actresses.json';
document.body.appendChild(a);
a.click();

P1 Badge Route actress exports through the desktop save helper

In the Wails desktop app, especially macOS, blob-backed anchor[download] clicks are dropped because the webview has no download delegate. Replacing saveJsonFile with this direct anchor flow makes Actress Export report success without saving anything; it also bypasses the native save dialog and streaming path intended for very large exports.


if (!confirm(m.actresses_import_confirm({ count: actresses.length }))) return;

P1 Badge Use the in-app confirmation for desktop imports

On the macOS Wails webview, native confirm() is unsupported because no WKUIDelegate confirmation handler is installed. Actress imports therefore cannot reliably reach importMutation.mutate on that platform; use the existing confirmDialog store, as the other import pages do, so the confirmation is rendered inside the app.


const posterChanged =
currentMovie.poster_url !== original.poster_url ||
currentMovie.cropped_poster_url !== original.cropped_poster_url ||
currentMovie.should_crop_poster !== original.should_crop_poster;

P2 Badge Clear manual crop geometry when resetting a poster

If a user applies a manual poster crop and then chooses Reset while the poster URL and crop-intent fields still match the scraped baseline, poster_crop_bounds is no longer considered drift, so Reset becomes disabled or no-ops and the pending geometry remains. Even when another poster field differs, the reset update does not null the bounds, allowing the unwanted crop to be saved or propagated to multipart siblings.



P2 Badge Remove the vendored node_modules backup

This commit adds roughly 16,300 dependency files totaling about 202 MB under node_modules_bak. The repository .dockerignore excludes only web/frontend/node_modules/, while the Dockerfile copies both web/frontend/ and later the whole repository, so this backup is uploaded in every Docker build context and copied into multiple build stages despite npm ci installing dependencies independently.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@seeyabye

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1ec626b14f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread web/frontend/src/routes/manual/+page.svelte
Comment thread web/frontend/src/routes/actresses/components/ActressToolbar.svelte
Comment thread web/frontend/src/routes/actresses/stores/actress-store.svelte.ts
@github-actions github-actions Bot added the 🤖 codex: needs work Codex review found issues that need addressing label Aug 15, 2026
@seeyabye

Copy link
Copy Markdown
Contributor Author

@codex review

@github-actions github-actions Bot added 🤖 codex: ok Codex review found no major issues and removed 🤖 codex: needs work Codex review found issues that need addressing labels Aug 15, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

Reviewed commit: 1ec626b14f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@seeyabye
seeyabye merged commit 470bf99 into integ/actress-sync-p12 Aug 15, 2026
4 checks passed
@seeyabye
seeyabye deleted the feat/actress-frontend-sync branch August 15, 2026 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🤖 codex: ok Codex review found no major issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant