Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bb2e5720bf
ℹ️ 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".
| })); | ||
| } | ||
| async function loadPlans(projectRoot, flow) { | ||
| const config = loadVnextConfig(projectRoot); |
There was a problem hiding this comment.
Honor --domain when loading the solution
In a multi-solution workspace, wf --domain partner indexes generate still loads the default vnext.config.json: the root hook forwards domain into the command options, but generate() passes only options.flow to loadPlans(), and this call hard-codes the default solution file. The command therefore silently emits SQL and a manifest for the wrong domain; with --retire-obsolete, executing that batch against the selected domain's database could retire or recreate projections from the default domain. Load the requested solution (or reject --domain) rather than ignoring the option.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
🟡 Changes recommended
loadPlans(..., flow) currently enforces schema-name collision validation across all workflows before applying the --flow filter, which can incorrectly block scoped generation.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
This PR adds a new offline CLI capability (wf indexes generate) to generate DBA-reviewed SQL scripts for attribute-index maintenance based on local workflow + Master schema definitions, without contacting the API or database.
Changes:
- Added
wf indexes generatecommand that produces an immutable batch of per-flow SQL files plus a manifest and execution notes. - Implemented offline planning (Master resolution, field extraction, projection/index definitions) and deterministic SQL generation with reconciliation/retirement logic.
- Added Node 18+ offline tests plus an optional PostgreSQL integration suite (gated by
VNEXT_INDEX_TEST_URL), and documented the new workflow.
File summaries
| File | Description |
|---|---|
| test/indexes.test.js | Adds offline unit tests for version selection, schema validation, deterministic naming, and end-to-end offline generation. |
| test/indexes.postgres.test.js | Adds optional integration tests that execute generated SQL against PostgreSQL to validate replay/reconciliation/retirement behaviors. |
| src/lib/indexes/versions.js | Implements runtime-aligned component version parsing and “best match” selection (including -pkg. revisions). |
| src/lib/indexes/sql.js | Generates deterministic per-flow SQL with conversion guards, index signature comparison, adoption/rebuild logic, and optional retirement. |
| src/lib/indexes/definitions.js | Loads local workflow/Master inputs, validates/merges indexed field requirements, and builds per-flow plans for SQL generation. |
| src/commands/indexes.js | Implements the indexes generate command: renders SQL, writes immutable batches, and produces a manifest/README. |
| README.md | Documents the new offline SQL generator command, its outputs, and how DBAs should execute and roll back scripts. |
| CLAUDE.md | Updates repository guidance to include the new index SQL tests and outlines the “strictly offline” contract. |
| bin/workflow.js | Wires the new wf indexes generate Commander subcommand and its options into the CLI entrypoint. |
Review details
- Files reviewed: 8/9 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| } | ||
| const [workflows, schemas] = await Promise.all([read(dirs.workflows, 'sys-flows'), read(dirs.schemas, 'sys-schemas')]); | ||
| const schemaOwners = new Map(); | ||
| for (const w of workflows.filter(w => w.domain === config.domain)) { |
Summary
Add
wf indexes generateto prepare attribute-index SQL from local workflow and Master schema definitions. The command writes a new batch of SQL files and a source manifest without contacting the API or database.DBA teams review and execute the generated SQL during a planned maintenance window. The scripts reconcile generated columns and indexes with existing database structures, reuse equivalent indexes and update the runtime’s ready-projection catalog.
Key Changes
x-indexedon nested scalar fields while retainingx-filterOperatorsandx-sortableas filtering and sorting permissions.--retire-obsoletefor planned retirement when all active workflow versions are available locally.Implementation Details
Command usage
Run from a workspace containing
vnext.config.json:Each invocation creates a separate batch directory containing:
.sqlfile per selected workflow.manifest.jsonwith source paths, component versions, checksums and physical index definitions.README.txtwith execution and rollback guidance.No database flag or connection is required. Generation is not invoked automatically by
sync,updateor Master publication.Master schema example
Add
x-indexed: trueto eligible fields in the Master component’sattributes.schema:{ "type": "object", "properties": { "amount": { "type": "number", "x-indexed": true, "x-filterOperators": ["gt", "between"], "x-sortable": true }, "createdAt": { "type": "string", "format": "date-time", "x-indexed": true, "x-filterOperators": ["between"] }, "customer": { "type": "object", "properties": { "name": { "type": "string", "x-indexed": true, "x-filterOperators": ["contains", "startsWith"], "x-sortable": true } } } } }Supported indexed types are
string,number,integerandboolean. Date-time fields useformat: "date-time". Unsupported array, object, reference and conditional index declarations fail validation.Full package revisions remain pinned.
latestand partial version selectors follow runtime-compatible ordering. Missing referenced schemas, duplicate component identities, conflicting field storage types and physical schema-name collisions fail generation.Generated database structures
numericgenerated column and B-tree indextimestamptzgenerated column and B-tree indextextgenerated column and B-tree indexesProjection keys retain the runtime’s
v1:latestcontract. Text projections remain available alongside numeric/date projections to preserve textual comparison semantics.Generated expressions populate values only for current rows, and indexes use
WHERE "IsLatest" = true. Before adding a projection, SQL checks conversion compatibility across current and historical data. Conversion failures report the field and roll back the transaction. Date-time conversion requires an explicit ISO-8601 offset and is independent of session time-zone settings.DBA execution and reconciliation
Each script uses a transaction, an advisory transaction lock and an
ACCESS EXCLUSIVEtable lock. New stored generated columns are added together to consolidate the table rewrite. The default lock timeout is five seconds.Index comparison includes keys, included columns, ordering, collation, operator classes, access method and partial predicates. Equivalent indexes can be adopted under existing names. Replaying an unchanged batch preserves index OIDs and skips conversion scans, table rewrites and
ANALYZE.This is maintenance-window DDL, not concurrent index creation. Text-search indexes require
pg_trgminpublicand thetr-TR-x-icucollation.Retirement and runtime activation
Retirement requires a complete local inventory of all still-active workflow versions. The offline generator cannot verify deployment state.
Retirement removes obsolete generated expressions and owned indexes, marks catalog entries unavailable and retains columns and stored values. Readers and writers must be drained for this operation.
The companion runtime uses
AttributeIndexes:Enabledto activate ready-projection routing andAttributeIndexes:DisabledFlowsfor per-flow rollback. Catalog refresh defaults to 30 seconds. Physical cleanup remains a separate maintenance operation.Validation
The PostgreSQL suite is included but was not rerun after the latest master merge. It can be executed against a disposable database:
Validation completed:
node --test test/indexes.test.js: 7 passed, 0 failed after the master merge and discovery-interface adaptation.