Skip to content

fix(publish): preserve related database templates - #462

Merged
appflowy merged 7 commits into
mainfrom
codex/published-relation-template
Aug 11, 2026
Merged

fix(publish): preserve related database templates#462
appflowy merged 7 commits into
mainfrom
codex/published-relation-template

Conversation

@appflowy

@appflowy appflowy commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

What changed

  • Load the template destination hierarchy with depth=2, guard against stale workspace responses, and distinguish retryable failures from an empty space list.
  • Resolve published relation rows from the attached snapshot before falling back to the live row service.
  • Restore duplicated relation database identities from the duplication URL, persisted mappings, or refreshed workspace metadata.
  • Display relation targets with their database container names instead of their first internal view names.
  • Add a fixture-backed Playwright BDD feature covering five cross-account document-template cases: referenced database, inline database, referenced page, nested referenced database, and nested inline database.
  • Extend the relation-template fixture scenario to assert that a copied relation database is named Related DB, while its relation cell resolves before and after reload.
  • Every template scenario uses a different consumer account and clicks Start with this template.

Validation

  • Existing focused Web unit tests for space loading, relation snapshots, relation names, and duplication mappings: passed.
  • pnpm test:e2e:bdd --grep @published-document-template-dependencies: 5 passed.
  • pnpm exec playwright test -c playwright.bdd.config.ts --grep @published-relation-template --workers=1: 1 passed, including the depth-2 destination request and copied database name.
  • Playwright BDD generation and Prettier checks passed.

Server dependency

Requires AppFlowy-Cloud-Premium PR #982 for recursive publication of referenced pages, nested database dependencies, relation remapping, and relation-target container names.

@sourcery-ai

sourcery-ai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR hardens the publish-duplicate flow so destination spaces are loaded reliably with shallow hierarchies and failures are surfaced, and ensures published database relations resolve from the snapshot rather than private live rows, backed by unit tests and an end-to-end Playwright BDD scenario.

Sequence diagram for destination space loading and retry in publish duplicate flow

sequenceDiagram
  actor User
  participant DuplicateModal
  participant useLoadWorkspaces
  participant WorkspaceService
  participant SpaceList

  User->>DuplicateModal: click StartWithThisTemplate
  DuplicateModal->>useLoadWorkspaces: loadSpaces(selectedWorkspaceId)
  useLoadWorkspaces->>WorkspaceService: getFolder(selectedWorkspaceId, 2)
  alt [request fails]
    useLoadWorkspaces->>useLoadWorkspaces: setSpaceError(true)
    useLoadWorkspaces->>useLoadWorkspaces: setSpaceList([])
    useLoadWorkspaces->>DuplicateModal: spaceError=true
    DuplicateModal->>SpaceList: render with error=true
    User->>SpaceList: click onRetry
    SpaceList->>DuplicateModal: onRetry()
    DuplicateModal->>useLoadWorkspaces: loadSpaces(selectedWorkspaceId)
    useLoadWorkspaces->>WorkspaceService: getFolder(selectedWorkspaceId, 2)
  else [request succeeds]
    useLoadWorkspaces->>useLoadWorkspaces: setSpaceError(false)
    useLoadWorkspaces->>useLoadWorkspaces: setSpaceList(spaces)
    useLoadWorkspaces->>DuplicateModal: spaceList
    DuplicateModal->>SpaceList: render with spaceList
  end
  opt [workspace changed during request]
    useLoadWorkspaces->>useLoadWorkspaces: requestId check
    useLoadWorkspaces-->>useLoadWorkspaces: ignore stale response
  end
Loading

Sequence diagram for published database row resolution from snapshot

sequenceDiagram
  participant PublishProvider
  participant createSnapshotRenderDoc
  participant createDatabaseYjsRenderDocsFromSnapshot
  participant RowService

  PublishProvider->>createSnapshotRenderDoc: snapshot
  alt [snapshot.kind === database]
    createSnapshotRenderDoc->>createDatabaseYjsRenderDocsFromSnapshot: snapshot
    createDatabaseYjsRenderDocsFromSnapshot-->>createSnapshotRenderDoc: { doc, rowMap }
    createSnapshotRenderDoc->>PublishProvider: register rowMap in databaseRowDocsRef
  else [snapshot.kind !== database]
    createSnapshotRenderDoc-->>PublishProvider: createDocumentYjsRenderDocFromSnapshot(snapshot)
  end

  PublishProvider->>PublishProvider: createRow(rowKey)
  alt [snapshotRow exists]
    PublishProvider-->>PublishProvider: return databaseRowDocsRef.get(rowKey)
  else [no snapshotRow]
    PublishProvider->>RowService: create(rowKey)
    RowService-->>PublishProvider: YDoc
  end
Loading

File-Level Changes

Change Details Files
Make workspace space loading robust, shallow, and distinguish failures from empty results in the duplicate modal.
  • Convert getWorkspaceFolder to accept a configurable depth and use depth=2 for destination space loading.
  • Track space request ids and the last-loaded workspace id to ignore stale responses and clear space lists on workspace changes.
  • Add spaceError state and expose it from useLoadWorkspaces to drive retry UI.
  • Reset selected space id on each load and only clear loading/error states for the latest request.
src/components/publish/header/duplicate/useDuplicate.ts
src/application/services/js-services/http/workspace-api.ts
Update the duplicate modal space list UI to show retry affordance on failures and a dedicated message for genuinely empty workspaces.
  • Extend SpaceList props with error and onRetry to differentiate failure vs empty list.
  • Render an alert row with translated error text and a Retry button when error=true.
  • Render a "No spaces available" message when there is no error and the space list is empty.
  • Wire DuplicateModal to pass spaceError to SpaceList and trigger loadSpaces on retry.
src/components/publish/header/duplicate/SpaceList.tsx
src/components/publish/header/duplicate/DuplicateModal.tsx
src/@types/translations/en.json
Ensure published database views and related rows are resolved from the published snapshot, not private live rows, and cache row docs from snapshot creation.
  • Replace snapshotToRenderDoc with a createSnapshotRenderDoc callback that captures both the database doc and per-row docs from createDatabaseYjsRenderDocsFromSnapshot.
  • Maintain a databaseRowDocsRef map keyed by row guid to serve createRow requests from snapshot data when available.
  • Clear snapshot row document refs when the snapshot changes to avoid leaks.
  • Adjust loadView to use createSnapshotRenderDoc for both initial snapshot loads and subsequent PublishService.getViewInfo responses.
  • Extend context tests to verify that createRow returns the published row doc and RowService.create is not called when the row exists in the snapshot.
src/application/publish/context.tsx
src/application/publish/__tests__/context.test.tsx
Add unit tests for the updated workspace/space-loading hook and space list UI behavior.
  • Mock WorkspaceService and auth hooks to deterministically exercise useLoadWorkspaces.
  • Verify spaceError is set on failure, cleared on retry, and that getFolder is called with depth=2.
  • Test handling of accounts without workspaces and ignoring stale folder responses after switching workspaces.
  • Test SpaceList rendering of retry UI vs empty-workspace message based on error and spaceList props.
src/components/publish/header/duplicate/useDuplicate.test.ts
src/components/publish/header/duplicate/SpaceList.test.tsx
Introduce a Playwright BDD scenario that validates published relation templates, destination selection behavior, and duplication correctness end-to-end.
  • Add a feature file describing the published relation template scenario using the pdf_db_relation@appflowy.io fixture.
  • Implement step definitions that publish only the source database, open the published template from another account, start with the template in a General space, and verify relation content and access behaviour.
  • Use API helpers to inspect workspace folders at depth=2, track created destination roots, and clean them up in After hooks.
  • Add helpers to manage publish state for the fixture views, ensuring databases start unpublished and are restored after the test.
playwright/bdd/features/database/published-relation-template.feature
playwright/bdd/steps/published-relation-template.steps.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai 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.

Hey - I've left some high level feedback:

  • The published-relation-template.steps.ts file is quite large and mixes generic helper utilities with scenario definitions; consider extracting reusable helpers (API wrappers, workspace traversal, auth-token access) into shared support modules to keep the step file focused and easier to maintain.
  • In useLoadWorkspaces, the request-cancellation logic using spaceRequestIdRef and the unmount useEffect is somewhat opaque; adding a dedicated "canceled" flag or wrapping the pattern in a small helper could make the intent clearer and reduce the chance of future misuse when this hook evolves.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `published-relation-template.steps.ts` file is quite large and mixes generic helper utilities with scenario definitions; consider extracting reusable helpers (API wrappers, workspace traversal, auth-token access) into shared support modules to keep the step file focused and easier to maintain.
- In `useLoadWorkspaces`, the request-cancellation logic using `spaceRequestIdRef` and the unmount `useEffect` is somewhat opaque; adding a dedicated "canceled" flag or wrapping the pattern in a small helper could make the intent clearer and reduce the chance of future misuse when this hook evolves.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@github-actions

Copy link
Copy Markdown

🥷 Ninja i18n – 🛎️ Translations need to be updated

Project /project.inlang

lint rule new reports level link
Missing translation 56 warning contribute (via Fink 🐦)

@appflowy
appflowy merged commit d3981b5 into main Aug 11, 2026
13 checks passed
@appflowy
appflowy deleted the codex/published-relation-template branch August 11, 2026 04:17
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.

1 participant