Skip to content

[sync] T6406 fix filtered link propagation and guard conditional lookup inserts#3616

Open
tea-artist wants to merge 1 commit into
developfrom
sync/ee-20260721-062654
Open

[sync] T6406 fix filtered link propagation and guard conditional lookup inserts#3616
tea-artist wants to merge 1 commit into
developfrom
sync/ee-20260721-062654

Conversation

@tea-artist

@tea-artist tea-artist commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

🔄 Automated sync from EE repository.

54 commit(s) synced since last sync.

Authors

Included commits

  • T6406 fix filtered link propagation and guard conditional lookup inserts (nichenqin)
  • feat(t5401): space-scoped scheduling — distributed semaphore, per-generation task pipeline, workflow admission (Uno)
  • feat(admin): reset user password via one-time link with email delivery T6389 (Boris)
  • feat(t6384): plain shell variant for dashboard/workflow/app entries (Aries X)
  • T6386 share PostgreSQL pools across backend database clients (nichenqin)
  • feat(t6384): show the transition skeleton for pinned base/table/view links (Aries X)
  • perf(t6384): speed up space-to-base entry and add transition skeleton (Aries X)
  • perf(t6383): per-view snapshot cache for jump-free view switching (Aries X)
  • T6387 perf(v2): parallelize computed activity publishing (nichenqin)
  • perf(t6361): queue-driven credit allocator replaces the charge-path advisory lock (Uno)
  • fix: deduplicate computed task load accounting (nichenqin)
  • T6382 fix(v2): use schema-aware compute activity queries (nichenqin)
  • perf(t6376): optimistic column reorder in grid view (Aries X)
  • fix(table): prevent table page stuck on viewless URL after shallow navigation T6378 (Aries X)
  • feat(t6368): in-app invite notifications for space/base collaborators (Uno)
  • perf(v2): make computed outbox advisory locks non-blocking (nichenqin)
  • perf(v2): reduce computed outbox read-after-write latency T6379 (nichenqin)
  • fix(T6309): improve kanban stacking field dialog (Jun Lu)
  • feat(T6375): update changelog banner to Teable 3.0 (Jocky Zhou)
  • fix(invite): move invitation rate-limit auto-ban to EE and exempt paid spaces T6369 (Aries X)
  • fix(history): prevent record history crashes T6344 (Jun Lu)
  • T6373 perf(v2): reuse date formatters (nichenqin)
  • fix(v2): plan symmetric link names against rolling table state (nichenqin)
  • fix(sql-query): serialize read-only role provisioning T6358 (nichenqin)
  • T6258 perf(table): concurrent seed prefetch and loading skeleton for table switch (Aries X)
  • fix(search): cast pg_indexes name columns to text in index info query T6354 (Aries X)
  • fix(invite): improve email input focus T5484 (Jun Lu)
  • fix(view): wake record subscriptions and rotate doc-ids cache after manual sort T6349 (Boris)
  • T6341 feat(v2): add substring search access paths (nichenqin)
  • feat(observability): space-load exporter for db-pool advisor (T6351) (Bieber)
  • fix(sdk): link selector field columns not respecting visibleFieldIds on self-link T6347 (Uno)
  • feat(T6294): improve compute activity status UI (Jun Lu)
  • perf(sdk): reduce initial record load from 300 to 100 rows T6257 (Aries X)
  • fix: reduce table info width (T6161) (Jun Lu)
  • fix: link share primary field visibility and SSRF trusted-origin handling (Uno)
  • T6346 feat(storage): support S3 path-style addressing for browser-facing presigned URLs (Bieber)
  • fix(share): copy base share 500 when plugin panel exists outside shared scope T3516 (Aries X)
  • T6276 Heal stuck calculating field activity (nichenqin)
  • T6332 fix lookup-of-formula convert lock (nichenqin)
  • fix(trash): table trash 500 on bulk-deleted records T6338 (SkyHuang)
  • T6339 fix cross-base computed target locking (nichenqin)
  • fix(setting): never cache canary spaceIds in setting redis blob T6328 (nichenqin)
  • fix: base share dialog crash while short link loads, embed uses long URL (T6337) (Aries X)
  • fix(sdk): avoid refetching fields when switching views T6340 (Boris)
  • fix: short link page 404 in hosted deployments and long URL flash (T6337) (Aries X)
  • fix(t5082): implement SSRF protection with safe-fetch utilities (Uno)
  • feat: short links for share views, base shares and templates (T5498) (Aries X)
  • feat: add ALLOW_CROSS_SPACE_REFERENCE env for self-hosted cross-space links T6329 (Aries X)
  • fix(v2): always register search vector maintenance projection DI (T6333) (nichenqin)
  • feat: improve cuppyclaw steering and agent protocol T6312 T6271 T6267 T6260 T6207 T6184 (Pengap)
  • fix: format attachment statistics size (T6313) (Jun Lu)
  • fix(setting): omit canary spaceIds from FORCE_V2_ALL setting cache T6328 (nichenqin)
  • fix(v2): prevent obsolete computed dead letters T6326 (nichenqin)
  • fix: unstick trash cleanup on dead BYODB drops and oversized workflow run-step deletes T6321 (Uno)

Latest source commit: teableio/teable-ee@ccc4386

This PR was automatically created by the sync workflow.

@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: 6c806776f0

ℹ️ 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 on lines +511 to +516
handleBestEffortDataDbDropError({
error,
isMetaFallback,
logger: this.logger,
target: `table ${table.id}`,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Skip invalidation after swallowed BYODB drop failures

When this new handler swallows a dead BYODB drop, dropTables still falls through to invalidateDroppedTable. That invalidator resolves a V2 container via getContainerForBase, and on a cold cache container creation calls createTypeValidationStrategy, which immediately executes a query against the same data DB; for the deleted Supabase tenant/auth-failure case being handled here, that reconnect fails again and the trash cleanup remains stuck. Consider skipping or making the cache invalidation best-effort when the physical drop was already swallowed.

Useful? React with 👍 / 👎.

Comment on lines +981 to +983
const { isMetaFallback } = await this.dataDbClientManager.getDataDatabaseForBase(baseId, {
useTransaction: true,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Avoid re-resolving BYODB routes after resolution failures

When the BYODB connection is already in error or needs migration, dataPrismaForBase can fail while DataDbClientManager.resolveSpaceDataDb runs ensureConnectionMigrated; this catch then calls getDataDatabaseForBase, which takes the same migration/connect path again before returning isMetaFallback. In that state the dead-tenant/auth failure never reaches handleBestEffortDataDbDropError, so permanent base deletion remains stuck instead of being swallowed.

Useful? React with 👍 / 👎.

Comment on lines +251 to +253
if (!classification || classification.retryable) {
throw error;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restrict which non-retryable drop errors are swallowed

Because this only rethrows retryable or unclassified errors, a live BYODB that rejects the DDL with a classified non-retryable error such as Postgres 42501 (data_db.permission_denied) is logged and swallowed. In that scenario the metadata cleanup commits even though the physical table/schema was not dropped, leaving customer data orphaned in a reachable database; the helper should allowlist the missing/deleted/auth-failure cases it intends to tolerate rather than every non-retryable classification.

Useful? React with 👍 / 👎.

@tea-artist tea-artist changed the title [sync] fix: unstick trash cleanup on dead BYODB drops and oversized workflow run-step deletes T6321 [sync] fix(v2): prevent obsolete computed dead letters T6326 Jul 21, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from 6c80677 to b39c6f8 Compare July 21, 2026 07:55
@tea-artist tea-artist changed the title [sync] fix(v2): prevent obsolete computed dead letters T6326 [sync] fix(setting): omit canary spaceIds from FORCE_V2_ALL setting cache T6328 Jul 21, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from b39c6f8 to 6eefd41 Compare July 21, 2026 07:57
@tea-artist tea-artist changed the title [sync] fix(setting): omit canary spaceIds from FORCE_V2_ALL setting cache T6328 [sync] fix: format attachment statistics size (T6313) Jul 21, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from 6eefd41 to da63387 Compare July 21, 2026 08:04
@tea-artist tea-artist changed the title [sync] fix: format attachment statistics size (T6313) [sync] feat: improve cuppyclaw steering and agent protocol T6312 T6271 T6267 T6260 T6207 T6184 Jul 21, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from da63387 to c88d1ad Compare July 21, 2026 08:11

@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: c88d1add52

ℹ️ 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".

return rows.map((row) => ({
...row,
content: parseSettingContent(row.content),
content: stripCanarySpaceIdsForForceV2Cache(row.name, parseSettingContent(row.content)),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid stripping canary IDs from API reads

When FORCE_V2_ALL=true, this stripped value is what SettingService.getSetting() returns to clients, not just what Redis stores. The admin canary settings UI reads that response and, when toggling the canary switch, posts spaceIds: canaryConfig?.spaceIds ?? [], so with an existing canary list a save under FORCE_V2_ALL overwrites the DB with an empty list. Keep the lean cache separate from the API/model value or omit spaceIds on unrelated updates.

Useful? React with 👍 / 👎.

@coveralls

coveralls commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 30182342037

Coverage decreased (-8.2%) to 50.492%

Details

  • Coverage decreased (-8.2%) from the base build.
  • Patch coverage: Could not be determined — this PR's diff is too large for GitHub to return (406 error at GitHub).
  • 8485 coverage regressions across 184 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

8485 previously-covered lines in 184 files lost coverage.

Top 10 Files by Coverage Loss Lines Losing Coverage Coverage
apps/nestjs-backend/src/features/space/space-data-db-migration.service.ts 1748 4.24%
apps/nestjs-backend/src/features/integrity/link-integrity.service.ts 313 3.08%
apps/nestjs-backend/src/features/field/open-api/field-open-api-v2.service.spec.ts 268 0.0%
apps/nestjs-backend/src/features/base/base-duplicate.service.spec.ts 222 0.0%
apps/nestjs-backend/src/features/base/base-export.service.ts 209 39.05%
apps/nestjs-backend/src/features/base/base-duplicate.service.ts 196 63.4%
apps/nestjs-backend/src/features/space/space-data-db-copy.integration.spec.ts 194 0.0%
apps/nestjs-backend/src/features/field/open-api/field-open-api.service.ts 191 64.82%
apps/nestjs-backend/src/features/share/share.service.ts 168 12.68%
apps/nestjs-backend/src/features/record/query-builder/formula-support-generated-column-validator.ts 165 0.0%

Coverage Stats

Coverage Status
Relevant Lines: 61746
Covered Lines: 31177
Line Coverage: 50.49%
Relevant Branches: 10523
Covered Branches: 7085
Branch Coverage: 67.33%
Branches in Coverage %: No
Coverage Strength: 1664.27 hits per line

💛 - Coveralls

@tea-artist tea-artist changed the title [sync] feat: improve cuppyclaw steering and agent protocol T6312 T6271 T6267 T6260 T6207 T6184 [sync] fix(v2): always register search vector maintenance projection DI (T6333) Jul 21, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from c88d1ad to 3a17e14 Compare July 21, 2026 09:53
@tea-artist tea-artist changed the title [sync] fix(v2): always register search vector maintenance projection DI (T6333) [sync] feat: add ALLOW_CROSS_SPACE_REFERENCE env for self-hosted cross-space links T6329 Jul 21, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from 3a17e14 to 13870f4 Compare July 21, 2026 10:07
@tea-artist tea-artist changed the title [sync] feat: add ALLOW_CROSS_SPACE_REFERENCE env for self-hosted cross-space links T6329 [sync] feat: short links for share views, base shares and templates (T5498) Jul 21, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from 13870f4 to ce9b62f Compare July 21, 2026 10:12
@tea-artist tea-artist changed the title [sync] feat: short links for share views, base shares and templates (T5498) [sync] fix(t5082): implement SSRF protection with safe-fetch utilities Jul 21, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from ce9b62f to b81a1d2 Compare July 21, 2026 10:46
@tea-artist tea-artist changed the title [sync] fix(t5082): implement SSRF protection with safe-fetch utilities [sync] fix: short link page 404 in hosted deployments and long URL flash (T6337) Jul 21, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from b81a1d2 to 6a80708 Compare July 21, 2026 12:05

@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: 6a807086cc

ℹ️ 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".

// Central policy switch: with the escape hatch on, nothing counts as a
// cross-space target, which disables the create-forbid and the
// field-duplicate downgrade in one place.
if (isCrossSpaceReferenceAllowed()) return false;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Gate cross-space links by data-DB compatibility

When ALLOW_CROSS_SPACE_REFERENCE=true, this returns false before checking where the two tables live. The only data-DB guard added in this change blocks starting a new space migration, so an instance with spaces already bound to different data databases can now create a link/lookup across those spaces; later reads and computed updates route by one table’s data DB and try to join the foreign table on that same connection, where it does not exist. Please keep the escape hatch limited to pairs that share the same physical data DB, or reject it for already-migrated spaces.

Useful? React with 👍 / 👎.

if (!share) return '';
return getShareUrl(share.shareId);
}, [share]);
return shortUrl ?? (isFallback ? getShareUrl(share.shareId, origin) : '');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep a valid base-share URL while short link loads

When a base share already exists, useShortLink initially returns no shortUrl and no error, so this passes '' into BaseShareContent; that component always renders EmbedConfigPopover, which calls new URL(shareUrl) during render and throws on the empty string. Opening an existing base share dialog, or the duplicated node-share path, can therefore crash before the short-link request finishes; keep using the long URL or gate the embed controls while loading.

Useful? React with 👍 / 👎.

@tea-artist tea-artist changed the title [sync] fix: short link page 404 in hosted deployments and long URL flash (T6337) [sync] fix(sdk): avoid refetching fields when switching views T6340 Jul 21, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from 6a80708 to 9e4a2f7 Compare July 21, 2026 13:13
@tea-artist tea-artist changed the title [sync] fix(sdk): avoid refetching fields when switching views T6340 [sync] fix: base share dialog crash while short link loads, embed uses long URL (T6337) Jul 21, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from 9e4a2f7 to 3daac16 Compare July 21, 2026 13:16

@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: 3daac1639e

ℹ️ 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".

ICsvParser,
} from '@teable/v2-core';
import { domainError } from '@teable/v2-core';
import { safeFetch } from '@teable/v2-utils';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep browser parser off the Node SSRF barrel

When @teable/v2-container-browser is used, it imports PapaparseCsvParser, so this new root import pulls in @teable/v2-utils' ./ssrf barrel; that barrel also re-exports agents.ts/fetch.ts, which import Node-only request-filtering-agent and undici. Browser builds using the browser container now have those Node transport modules in the dependency graph and can fail to bundle or require unusable polyfills; import a browser-safe registry subpath or split the Node SSRF exports from the root barrel.

Useful? React with 👍 / 👎.

? { type: ShortLinkType.Template, resourceId: templateDetail.id }
: undefined
);
const displayShareUrl = shortUrl ?? (isFallback ? shareUrl : '');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep the publish success URL while short link is unavailable

After publishing a previously unpublished base, onSuccess sets shareUrl and immediately opens the success dialog, but templateDetail has not refetched as published yet, so useShortLink is disabled and isFallback is false. This expression therefore returns '', making the success dialog, copy button, external open, and social share actions use an empty URL until a later refetch/short-link request completes; keep the permalink from shareUrl in this loading/disabled state.

Useful? React with 👍 / 👎.

@tea-artist tea-artist changed the title [sync] fix: base share dialog crash while short link loads, embed uses long URL (T6337) [sync] fix(setting): never cache canary spaceIds in setting redis blob T6328 Jul 21, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from 3daac16 to 6bc7755 Compare July 21, 2026 13:33
@tea-artist tea-artist changed the title [sync] fix(setting): never cache canary spaceIds in setting redis blob T6328 [sync] T6339 fix cross-base computed target locking Jul 21, 2026
@tea-artist tea-artist changed the title [sync] T6341 feat(v2): add substring search access paths [sync] fix(view): wake record subscriptions and rotate doc-ids cache after manual sort T6349 Jul 22, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from 85a19ba to 4a43c0c Compare July 22, 2026 11:09
@tea-artist tea-artist changed the title [sync] fix(view): wake record subscriptions and rotate doc-ids cache after manual sort T6349 [sync] fix(invite): improve email input focus T5484 Jul 22, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from 4a43c0c to fd01730 Compare July 22, 2026 11:27
@tea-artist tea-artist changed the title [sync] fix(invite): improve email input focus T5484 [sync] fix(search): cast pg_indexes name columns to text in index info query T6354 Jul 22, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from fd01730 to 0e59d61 Compare July 22, 2026 12:09

@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: 0e59d617e6

ℹ️ 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 on lines +23 to +24
export const safeFetch: ISsrfSafeFetchFn = (url, init) =>
(registeredFetch ?? globalThis.fetch)(url, init);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Register SSRF-safe fetch before URL imports

When URL-backed CSV imports run through the public createV2OrpcRouter() default container path, createV2NodePgContainer() registers PapaparseCsvParser but no code calls setSafeFetch(createSsrfSafeFetch()); only the Nest V2ContainerService does that. Because safeFetch falls back to globalThis.fetch when unregistered, these imports still allow server-side requests to loopback/RFC1918 targets outside the Nest path, so register the guarded fetch in the node container/bootstrap path or fail closed when no implementation is registered.

Useful? React with 👍 / 👎.

@tea-artist tea-artist changed the title [sync] fix(search): cast pg_indexes name columns to text in index info query T6354 [sync] T6258 perf(table): concurrent seed prefetch and loading skeleton for table switch Jul 22, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from 0e59d61 to 087f28c Compare July 22, 2026 12:58

@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: 087f28c1f6

ℹ️ 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 on lines 1686 to +1688
.map((fieldDbName) => `coalesce(${quoteIdentifier(fieldDbName)}::text, '')`)
.join(` || ' ' || `);
return `to_tsvector(${quoteLiteral(languageConfig)}::regconfig, ${document || quoteLiteral('')})`;
.join(` || E'\\n' || `);
return `lower(${document || quoteLiteral('')})`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Normalize long-text search documents before LIKE prefilter

When V2_TABLE_QUERY_OPS_SEARCH_ACCESS_PATH_RUNTIME=auto uses a generated-text access path that covers a long-text field, this builds the indexed document from the raw column text, but the default search predicate in buildFieldSearchCondition replaces CR/LF/tabs with spaces before applying ILIKE. A cell containing foo\nbar therefore matches a search for foo bar on the default path, while the generated document fails the LIKE lower('%foo bar%') prefilter and the row is excluded before the exact predicate can recheck it. Use the same long-text projection as the default search builder, or avoid the prefilter for fields whose document text is not a superset of the exact predicate.

Useful? React with 👍 / 👎.

Comment on lines +337 to +338
this.configService.get('V2_TABLE_QUERY_OPS_SEARCH_ACCESS_PATH_RUNTIME') ??
this.configService.get('V2_TABLE_QUERY_OPS_SEARCH_VECTOR_RUNTIME')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Allow access-path rebuild tasks for the new runtime

When V2_TABLE_QUERY_OPS_SEARCH_ACCESS_PATH_RUNTIME=auto enables the task worker without manual index execution, this new env path makes searchVectorRuntimeEnabled true, but the default allowed kinds below still only include rebuild_search_vector. The schema-change scheduler now queues rebuild_search_access_path, and claimNextAccepted filters by allowedKinds, so those rebuilds are never claimed and the search config stays rebuild_pending instead of returning to ready. Include the new access-path rebuild kind in the default and parsed allowlists.

Useful? React with 👍 / 👎.

Comment on lines +766 to 769
(recordSearchAccessPath?.kind === 'generated_tsvector' ||
recordSearchAccessPath?.kind === 'generated_text') &&
query.search &&
query.includeQueryExtra !== true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve grouped query extras on generated-text search

When generated_text is selected for a searched V2 records request that also has groupBy or collapsedGroupIds, this early return skips getQueryExtra() entirely unless the caller explicitly sets includeQueryExtra=true. That drops extra.groupPoints/allGroupHeaderRefs even though the returned record ids are still grouped, so grouped REST clients cannot render the matching group headers during search; keep loading the group extras and only skip the expensive search-hit extra, or make grouped requests opt in automatically.

Useful? React with 👍 / 👎.

@tea-artist tea-artist changed the title [sync] T6258 perf(table): concurrent seed prefetch and loading skeleton for table switch [sync] fix(sql-query): serialize read-only role provisioning T6358 Jul 22, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from 087f28c to 3a8b2c4 Compare July 22, 2026 23:59

@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: 3a8b2c43b9

ℹ️ 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 on lines +80 to +81
const ssrDataFresh =
initialAnchorRef.current.tableId === tableId && initialAnchorRef.current.viewId === viewId;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Stop reusing the initial SSR snapshot after navigation

When the user shallow-navigates away from the page-load table/view and later returns to that same initial pair, this expression becomes true again, so useTableSeed is disabled and the providers are seeded from the original page-load props instead of a fresh bounded seed. In a long-lived session this can briefly show obsolete fields/records or allow interacting with stale doc-less records until the ShareDB query catches up; track that the user has left the initial anchor once, or invalidate the SSR snapshot on the first anchor change.

Useful? React with 👍 / 👎.

@tea-artist tea-artist changed the title [sync] fix(sql-query): serialize read-only role provisioning T6358 [sync] fix(v2): plan symmetric link names against rolling table state Jul 23, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from 3a8b2c4 to 014e76c Compare July 23, 2026 00:51
@tea-artist tea-artist changed the title [sync] fix(v2): plan symmetric link names against rolling table state [sync] T6373 perf(v2): reuse date formatters Jul 23, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from 014e76c to e251ac4 Compare July 23, 2026 05:16
@tea-artist tea-artist changed the title [sync] T6373 perf(v2): reuse date formatters [sync] fix(history): prevent record history crashes T6344 Jul 23, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from e251ac4 to 381b80d Compare July 23, 2026 06:26
@tea-artist tea-artist changed the title [sync] fix(history): prevent record history crashes T6344 [sync] fix(invite): move invitation rate-limit auto-ban to EE and exempt paid spaces T6369 Jul 23, 2026
@tea-artist
tea-artist force-pushed the sync/ee-20260721-062654 branch from 381b80d to fab7775 Compare July 23, 2026 06:37
@tea-artist tea-artist changed the title [sync] fix(invite): move invitation rate-limit auto-ban to EE and exempt paid spaces T6369 [sync] feat(T6375): update changelog banner to Teable 3.0 Jul 23, 2026

@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: bfa173325b

ℹ️ 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 on lines +143 to +148
const strippedFieldOptions = stripLookupFormulaExecutableOptions(field.options) ?? {};
const {
formatting = inheritableOptions.formatting,
showAs,
...inheritOptions
} = field.options as Record<string, unknown>;
} = strippedFieldOptions;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve null lookup showAs tombstones

When a regular lookup field has explicitly cleared an inherited display mode (options.showAs === null), this newly stripped field.options path extracts that null into showAs, but the later options rebuild only spreads showAs when it is truthy. If the linked/source field changes and updateLookupField runs, the null tombstone is dropped from the persisted options; after reload the lookup can inherit the source field's showAs again, undoing the user's clear. Preserve the property based on ownership (including null) rather than truthiness.

Useful? React with 👍 / 👎.

@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: fc1823befc

ℹ️ 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".


await this.checkInvitationLimits();

const departmentIds = this.cls.get('organization.departments')?.map((d) => d.id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restore the invitation rate-limit check

When MAX_INVITATIONS_PER_HOUR is configured, email invitations now proceed without any quota check because the only call to the removed checkInvitationLimits() was deleted and a repo-wide search shows no remaining reference to that env var. In deployments that relied on this setting for anti-abuse, a user can send unlimited invitations instead of being blocked/deactivated after the hourly threshold; keep the check here or replace it with an equivalent risk-control path.

Useful? React with 👍 / 👎.

SELECT EXISTS (
SELECT 1
FROM computed_task_field_ref AS refs
WHERE refs.table_id = ${tableId}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Add a table_id index before polling activity refs

This new reconciliation path runs on every compute-activity read and filters computed_task_field_ref by table_id, but the migration only creates computed_task_field_ref_field_id_idx, not a table_id index. On instances with many queued/completed compute refs, each healthy poll for any table has to scan the whole ref table (twice, including the grouped check below), which can make the diagnostics endpoint and toolbar polling expensive; add an index such as (table_id) or (table_id, field_id) with this query.

Useful? React with 👍 / 👎.

value.trim()
);
const exactOrigins = normalizeOrigins([
publicOrigin,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep PUBLIC_ORIGIN out of exact-origin SSRF trust

When PUBLIC_ORIGIN is an internal or loopback app URL, an authenticated URL import can submit an absolute URL on that origin such as /admin; attachmentUrlSchema accepts absolute http(s) URLs, and adding publicOrigin to exactOrigins makes createTrustedUrlPredicate() bypass the filtering agent for every path on that origin. This reopens the app-path SSRF case the schema is trying to block, so keep PUBLIC_ORIGIN limited to the attachment-read path unless an origin was explicitly configured as fully trusted.

Useful? React with 👍 / 👎.

@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: d6c7d342c3

ℹ️ 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 on lines +92 to +93
if (this.isLookup) {
return [];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restore lookup-formula link dependencies

When a regular lookup targets a formula (type === Formula and isLookup), this branch makes getReferenceFields() empty; because FormulaFieldCore.getLinkFields() still derives link dependencies only from those reference fields, it no longer returns the lookupOptions.linkFieldId. The record CTE builder relies on field.getLinkFields(this.table) to emit hidden link CTEs before resolving projected lookups, so lookup-formula values whose link field is hidden/not projected can be resolved without the required join and come back null. Keep expression references suppressed, but have getLinkFields() fall back to the base lookupOptions path for lookup fields.

Useful? React with 👍 / 👎.

@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: e82e385dc9

ℹ️ 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 on lines +895 to +899
this.eventEmitterService.emitAsync(
Events.COLLABORATOR_CREATE,
new CollaboratorCreateEvent(base.spaceId, {
resourceId: baseId,
resourceType: CollaboratorType.Base,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Defer invite notifications until collaborator transactions commit

When this helper is invoked inside existing transactions such as DashboardService.installPlugin (checked its $tx wrapper) or the plugin context-menu install flow, this new contextual event is emitted immediately after createMany, before the surrounding transaction performs later writes. If a later write rolls back, CollaboratorInviteNotificationListener can already have inserted/sent an invite notification for a collaborator that was never committed; either keep skipEvent for transactional callers and emit post-commit, or register the notification after the outer transaction commits.

Useful? React with 👍 / 👎.

@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

await this.deleteNodeShares(baseId, nodeId);

P2 Badge Move share cleanup after node deletion succeeds

If deleteResource() throws after this call (for example a table/drop or dashboard delete failure), the method exits before deleting the base_node, but deleteNodeShares() has already hard-deleted the node's base-share rows and marked their short links dead. That leaves the still-existing table/dashboard with its share links permanently revoked after a failed delete attempt; perform this cleanup only after the resource/node delete succeeds, or make the whole sequence transactional where possible.

ℹ️ 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".

const startIndex = queryRef.current.skip ?? 0;
const take = queryRef.current.take ?? LOAD_PAGE_SIZE;
lastMergedSkipRef.current = startIndex;
const isFirstFreshDelivery = pendingFreshRef.current && (extra != null || records.length > 0);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Treat empty record deliveries as fresh

When switching back to a cached grid whose current result is empty and ungrouped, the first ShareDB ready event has records.length === 0 and usually no extra, so this condition never marks it as the authoritative fresh delivery. The merge below then copies the seeded preLoadedRecords back into state instead of clearing them, and settledRef never evicts that snapshot, leaving rows from the previous result visible until another non-empty/extra update arrives. Treat the first ready/changed delivery as fresh even when it is empty, or use an explicit readiness signal, before retaining cached rows.

Useful? React with 👍 / 👎.

// previous view's structure — writing it here would poison the new
// view's slot, so skip until state and key agree again
if (keyChanged) return;
if (view?.id && groupPoints != null) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clear cached groups when grouping is removed

When a view that has cached groupPoints is later changed to an ungrouped view, the fresh subscription result typically has no groupPoints (and may have no extra), so this guard skips updating the cache. The old grouped structure remains in useGridViewCacheStore and is seeded the next time the user returns to the view, causing stale group headers/layout to appear for an ungrouped result until another grouped delivery overwrites it; clear the cached group facet when the authoritative result has no group points.

Useful? React with 👍 / 👎.

@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: 388019c370

ℹ️ 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 on lines +64 to +65
const { provider, publicUrl, publicBucket, privateBucket, privateBucketEndpoint, s3, minio } =
storageConfig();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include local encryption in preview cache fingerprint

When local storage is used and BACKEND_STORAGE_ENCRYPTION_KEY/IV is rotated while Redis/SQLite preview cache survives a deploy, this fingerprint does not change because it omits storageConfig().encryption. LocalStorage.getPreviewUrl() embeds an encrypted read token in the cached URL, so after rotation verifyReadToken() cannot decrypt the old token and attachment previews keep returning broken cached URLs until the preview cache TTL expires; include the encryption settings (digesting secrets like the S3/MinIO keys) in the config signature.

Useful? React with 👍 / 👎.

…up inserts

Synced from teableio/teable-ee@ccc4386

Co-authored-by: Aries X <caoxing9@gmail.com>
Co-authored-by: Bieber <artist@teable.io>
Co-authored-by: Boris <boris2code@outlook.com>
Co-authored-by: Jocky Zhou <jocky@teable.ai>
Co-authored-by: Jun Lu <hammond@teable.io>
Co-authored-by: Pengap <penganpingprivte@gmail.com>
Co-authored-by: SkyHuang <sky.huang.fe@gmail.com>
Co-authored-by: Uno <uno@teable.ai>
Co-authored-by: nichenqin <nichenqin@hotmail.com>

@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: 55b8263fd3

ℹ️ 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 on lines +90 to +92
Promise.resolve()
.then(() => view.updateColumnMeta(columnMetaRo))
.catch(() => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Serialize consecutive column-order writes

When a user performs a second drag before the first updateColumnMeta request settles, this launches another independent write whose order was calculated from the first drag's optimistic state, while persisting only the field moved by the second drag. If the first request then fails or the requests are applied out of order, the second write is committed against server ordering that never contained its prerequisite move, and the first rejection also clears the newer optimistic state, leaving a different column order than the user selected. Serialize these writes or persist/rollback each optimistic ordering as one versioned operation.

Useful? React with 👍 / 👎.

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