[sync] docs(community): README overhaul — workflow-first AI platform narrative#3612
Conversation
7330503 to
49dde00
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7330503fe1
ℹ️ 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 fieldIdPattern = new RegExp(`^${fieldIdPrefix}[0-9a-zA-Z]{${fieldIdBodyLength}}(?:_\\d+)?$`); | ||
| const legacyFieldIdMaxBodyLength = 64; | ||
| const fieldIdPattern = new RegExp( | ||
| `^${fieldIdPrefix}[0-9a-zA-Z]{1,${legacyFieldIdMaxBodyLength}}(?:_\\d+)?$` |
There was a problem hiding this comment.
Keep legacy IDs from overflowing DB column names
When an imported field has no dbFieldName, the Postgres schema repository falls back to field.id().toString() as the physical column name, and the adapter already treats 63 bytes as the Postgres identifier limit. This pattern now accepts fld plus a 64-character body (and optional suffix), so legacy IDs longer than 63 bytes can be stored as metadata but created/truncated differently by Postgres, making schema introspection/repair miss the column or causing collisions for IDs that share the first 63 bytes. Please cap only the fallback DB identifier length or hash/truncate the DB column name separately instead of accepting IDs that can become overlong columns.
Useful? React with 👍 / 👎.
| const fieldIdPattern = new RegExp(`^${fieldIdPrefix}[0-9a-zA-Z]{${fieldIdBodyLength}}(?:_\\d+)?$`); | ||
| const legacyFieldIdMaxBodyLength = 64; | ||
| const fieldIdPattern = new RegExp( | ||
| `^${fieldIdPrefix}[0-9a-zA-Z]{1,${legacyFieldIdMaxBodyLength}}(?:_\\d+)?$` |
There was a problem hiding this comment.
Update formula-reference scanners for legacy IDs
With this broader FieldId shape, {fldAccessKey} is now a valid v2 formula reference, but DotTea import still extracts dependencies with /fld[0-9a-zA-Z]{16}/g in packages/v2/dottea/src/normalizer/DotTeaFieldNormalizer.ts:60. For imported formulas that reference a missing legacy field ID, or a legacy rollup/conditionalRollup ID that the normalizer is supposed to downgrade, those checks see no dependency and keep the field as a formula; buildTableFromInput then fails later or preserves an unsupported dependency. Please update the formula-reference scanners used by import normalization to match the same legacy ID format.
Useful? React with 👍 / 👎.
49dde00 to
727b858
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 727b858d82
ℹ️ 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".
| (appConfig?.deployProvider === 'docker-runtime' && | ||
| Boolean(process.env.TEABLE_INFRA_API_URL && process.env.TEABLE_INFRA_API_KEY)), |
There was a problem hiding this comment.
Honor env deploy provider for app generation
When the deployment channel is left unset, the new schema documents that it falls back to APP_DEPLOY_PROVIDER, but this gate only enables Teable Infra when a persisted appConfig.deployProvider equals docker-runtime. In deployments that select the docker runtime via env and do not store a per-instance override, /setting/public still returns appGenerationEnabled: false even with TEABLE_INFRA_API_URL and TEABLE_INFRA_API_KEY configured, so clients hide app generation. Please resolve the effective provider from the env fallback before this check.
Useful? React with 👍 / 👎.
727b858 to
aed64ec
Compare
aed64ec to
08942f2
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 08942f246b
ℹ️ 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".
| appGenerationEnabled: | ||
| Boolean(appConfig?.vercelToken) || | ||
| (appConfig?.deployProvider === 'docker-runtime' && | ||
| Boolean(process.env.TEABLE_INFRA_API_URL && process.env.TEABLE_INFRA_API_KEY)), |
There was a problem hiding this comment.
Gate app generation by the selected deploy provider
When an instance already has a Vercel token and then switches appConfig.deployProvider to docker-runtime without TEABLE_INFRA_API_URL/TEABLE_INFRA_API_KEY, this expression still returns appGenerationEnabled: true because the Vercel token short-circuits the docker-runtime check, so clients can expose app generation even though the selected deployment channel cannot run. This is separate from the env-fallback issue already noted; the fresh evidence is the new Boolean(appConfig?.vercelToken) || ... branch enabling a docker-runtime configuration via stale Vercel credentials.
Useful? React with 👍 / 👎.
| cacheKey: connection.id, | ||
| connectionId: connection.id, | ||
| internalSchema: connection.internalSchema, | ||
| connectionUrl: decryptDataDbUrl(connection.encryptedUrl), |
There was a problem hiding this comment.
Use pooler-safe routing for outbox anomalies
For a BYODB target behind a pooler that rejects search_path startup parameters, this raw connectionUrl is only consumed by wakeup/inspect paths; listComputedOutboxMaintenanceAnomalies and recoverComputedOutboxMaintenanceAnomaly still open target.url and reference computed_update_* tables unqualified. Because target.url still contains the options=-c search_path=... parameter, the anomaly list/recovery endpoints continue to fail in the same pooler environment this change is trying to support; please route those paths through connectionUrl and schema-qualified table names too.
Useful? React with 👍 / 👎.
| /** Raw connection URL without Teable's internal-schema startup parameters. */ | ||
| connectionUrl?: string; |
There was a problem hiding this comment.
Route Knex clients through the raw pooler URL
This new raw connectionUrl is not used when dataKnexForSpace builds the cached Knex client, which still connects with resolved.url containing the options=-c search_path=... startup parameter. BYODB spaces behind the pooler covered by the new test will still fail on Knex-backed reads/writes such as cold record-history reads (record-history-flusher.service.ts) or view/index helpers that call dataKnexForTable; please have the Knex route use the raw URL plus explicit schema qualification/searchPath without the rejected startup option.
Useful? React with 👍 / 👎.
08942f2 to
ccd220e
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ccd220ecc9
ℹ️ 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".
| if (property === '$executeRawUnsafe') { | ||
| return (query: string, ...values: unknown[]) => | ||
| scopedTransaction((transaction) => transaction.$executeRawUnsafe(query, ...values)); |
There was a problem hiding this comment.
Avoid wrapping concurrent refreshes in transactions
For BYODB tables that use database views, DatabaseViewService.refreshView() calls executeDataPrismaForTable() with REFRESH MATERIALIZED VIEW CONCURRENTLY ...; after this change the scoped client's $executeRawUnsafe always runs inside scopedTransaction, so that refresh is executed in an interactive transaction and PostgreSQL rejects concurrent materialized-view refreshes in that context. Please keep a non-transactional raw execution path for statements that require autocommit, or avoid returning this transaction-wrapping proxy from txClient() for ordinary router execution.
Useful? React with 👍 / 👎.
| const pool = new Pool({ | ||
| connectionString, | ||
| max: resolvePoolMax(connectionString), | ||
| }); |
There was a problem hiding this comment.
When a BYODB database restarts or an idle connection is terminated, pg.Pool emits an error event for the idle client; this cached pool has no listener, unlike the existing Kysely pg pool setup, so the event can be unhandled and terminate the NestJS process. Please attach an error handler to the pool before handing it to Prisma.
Useful? React with 👍 / 👎.
| const scopedTransaction: ScopedTransaction = (fn, options) => | ||
| client.$transaction(async (transaction) => { | ||
| await transaction.$executeRawUnsafe(setLocalSearchPath); | ||
| return await fn(transaction); |
There was a problem hiding this comment.
Let callers set transaction characteristics first
For BYODB bases, BaseSqlExecutorService.executeQuerySql() runs through this scoped transaction and then issues SET TRANSACTION READ ONLY inside the callback, but this preamble has already executed a SELECT set_config(...) in the transaction. PostgreSQL requires SET TRANSACTION characteristics to be set before any query, so the SQL executor's read-only queries will fail on BYODB connections; please avoid a query preamble before the callback or provide a way to set transaction characteristics before the search path is applied.
Useful? React with 👍 / 👎.
| pool, | ||
| }), | ||
| }); | ||
| return config.pg.schema ? db.withSchema(config.pg.schema) : db; |
There was a problem hiding this comment.
Keep pg_trgm visible to raw V2 index tasks
For BYODB databases that already have pg_trgm installed in the space's internal schema, this only applies Kysely's withSchema plugin and does not put that schema on the runtime search_path. The V2 table-query remediation executor still runs raw CREATE EXTENSION IF NOT EXISTS pg_trgm and then CREATE INDEX ... gin_trgm_ops; raw SQL bypasses withSchema, so the extension no-ops but the unqualified opclass is not visible and remediation fails. Please set an appropriate local search path for these raw index tasks or qualify/migrate the extension before using gin_trgm_ops.
Useful? React with 👍 / 👎.
ccd220e to
1ad0ca6
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1ad0ca6854
ℹ️ 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 appConfigEnginePatchSchema = z.object({ | ||
| vercelToken: nullableStringSchema, | ||
| // null resets the channel back to env APP_DEPLOY_PROVIDER / vercel resolution | ||
| deployProvider: appConfigDeployProviderSchema.nullable().optional(), |
There was a problem hiding this comment.
Drop null deployProvider resets before persisting
When an admin uses the documented reset path (deployProvider: null), updateAppConfig() just merges this patch into the existing appConfig and stores it, so the setting now contains deployProvider: null even though appConfigSchema only allows the enum or absence. In that reset scenario the key is not actually removed for env/default resolution, and subsequent setting responses can carry an appConfig shape that the public schema does not accept; please normalize null by deleting the property before saving/returning it.
Useful? React with 👍 / 👎.
| inviteCode?: string, | ||
| autoSpaceCreation: boolean = true | ||
| ) { | ||
| user = { ...user, refMeta: this.withAffiliateVia(user.refMeta) }; |
There was a problem hiding this comment.
Capture affiliate tokens for placeholder signups
Because the cookie is merged only in createUserWithSettingCheck(), signup paths that reuse an existing passwordless/accountless user row bypass this line: local password signup updates that placeholder directly in local-auth.service.signup(), and OAuth/SSO attaches an account to the existing row in UserService.signInOrSignUp(). In those invite/precreated-user scenarios the same affiliate cookie is present but never persisted to refMeta, so attribution is silently lost for a supported signup path.
Useful? React with 👍 / 👎.
| const hasDurableTrigger = await hasUndoCaptureTrigger(db, tableKey); | ||
| if (hasDurableTrigger) { | ||
| cache.tableTriggers.add(tableKey); |
There was a problem hiding this comment.
Don’t cache transaction-local undo triggers
When ensureUndoCaptureInfrastructure() runs inside a transaction that has just created the undo trigger, this transaction-scoped probe now sees the uncommitted trigger and immediately adds the table to the root cache. If the outer unit of work later rolls back, the trigger disappears but future mutations skip installation because the cache says it is ready, so undo snapshots for that table are no longer captured; only cache this hit when the probe is not running on a transaction connection.
Useful? React with 👍 / 👎.
1ad0ca6 to
4481357
Compare
4481357 to
e0f22cb
Compare
e0f22cb to
d256d89
Compare
d256d89 to
5ff0007
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5ff0007b0f
ℹ️ 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 isSameRegion = | ||
| regionType === type || (isCellRegionType(regionType) && isCellRegionType(type)); | ||
| if (!isSameRegion) return; | ||
| if (regionType !== type) return; |
There was a problem hiding this comment.
Treat Cell and ActiveCell as the same click target
When an inactive cell is clicked, onMouseDown records the region as Cell, then selection makes the cell active before the subsequent click handler recomputes getMouseState() as ActiveCell. This strict comparison returns early for that normal Cell -> ActiveCell transition, so first-click cell renderer actions such as boolean toggles, ratings, links, and buttons are ignored until the user clicks again. Keep Cell and ActiveCell equivalent as before, or compare the target coordinates instead of the raw region type.
Useful? React with 👍 / 👎.
| const onMouseMove = () => { | ||
| clearDelayedHoverTimer(); | ||
| const { mouseState } = syncHoverState(); | ||
| onCellPosition(mouseState); |
There was a problem hiding this comment.
Pass the new hover coordinates to hit testing
Here setHoverCellPosition is asynchronous, so onCellPosition() still reads the previous render's hover coordinates; after the delayed active-cell hover sync was removed, active-only renderers such as select/image/user cells often have null or stale coords right after activation. If a user activates one of those cells and clicks an inline delete/preview/add control without moving the mouse again, checkRegion misses the control and the click is ignored. Pass the freshly computed hoverCellPosition into the hit test or keep a sync path after activation.
Useful? React with 👍 / 👎.
5ff0007 to
14485a2
Compare
14485a2 to
a881abd
Compare
a881abd to
c00de8d
Compare
c00de8d to
931e725
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 931e725fc8
ℹ️ 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 cleanUrl = request.nextUrl.clone(); | ||
| cleanUrl.searchParams.delete('via'); | ||
| response = NextResponse.redirect(cleanUrl); |
There was a problem hiding this comment.
Use browser-visible host for via cleanup redirects
When the Next app is self-hosted behind a reverse proxy, this module already accounts for request.nextUrl being the bind address (for example localhost) by deriving the cookie domain from Host/x-forwarded-host, but the cleanup redirect still clones request.nextUrl. In that setup, visiting https://app.teable.ai/?via=... can return a 307 Location like http://localhost:3000/, sending the user's browser to an internal or unreachable host after the cookie is set. Please make this redirect relative or reconstruct it from the browser-visible forwarded host before deleting via.
Useful? React with 👍 / 👎.
931e725 to
64b21bc
Compare
64b21bc to
2ffdd65
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2ffdd65e6b
ℹ️ 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 DIRTY_TABLE = 'pg_temp.tmp_computed_dirty'; | ||
| const DIRTY_TABLE_ID_COL = 'table_id'; | ||
| const DIRTY_RECORD_ID_COL = 'record_id'; | ||
| const BEFORE_IMAGE_TABLE = 'tmp_computed_before_image'; | ||
| const BEFORE_IMAGE_TABLE = 'pg_temp.tmp_computed_before_image'; |
There was a problem hiding this comment.
Avoid schema-qualifying temp table creation
When a computed update runs, these constants are used by resetDirtyTable / resetBeforeImageTable to compile CREATE TEMPORARY TABLE "pg_temp"."tmp_..."; PostgreSQL's CREATE TABLE docs state that temporary tables cannot be created with a schema-qualified name, so the worker fails before it can populate the dirty/before-image tables. Keep creation unqualified and only qualify later references through pg_temp, or otherwise create the temp relation with PostgreSQL-supported syntax. See: https://www.postgresql.org/docs/current/sql-createtable.html
Useful? React with 👍 / 👎.
2ffdd65 to
c2b8473
Compare
…narrative Synced from teableio/teable-ee@2e5904f 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: Jun Lu <hammond@teable.io> Co-authored-by: Uno <uno@teable.ai> Co-authored-by: nichenqin <nichenqin@hotmail.com>
c2b8473 to
8c0143d
Compare
🧹 Preview Environment Cleanup
|
🔄 Automated sync from EE repository.
23 commit(s) synced since last sync.
Authors
Included commits
Latest source commit: teableio/teable-ee@2e5904f
This PR was automatically created by the sync workflow.