Repository navigation
feat(projects): enforce Project membership and retire the connector - #8590
mzxchandra wants to merge 98 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…ty-enforcement # Conflicts: # apps/sim/lib/projects/__integration__/foundation.integration.ts
…t-entity-enforcement # Conflicts: # apps/sim/lib/billing/organizations/lock-order.test.ts # apps/sim/lib/projects/__integration__/foundation.integration.ts # apps/sim/lib/projects/environment-source.ts
|
@cubic-dev-ai review this PR |
@mzxchandra I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 172 files
Heads up: you’ve reached your flex budget. Increase your flex budget or wait for usage to reset.
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Turn on auto-fix | Re-trigger cubic
…t-entity-enforcement # Conflicts: # apps/sim/lib/workspaces/admin-move.test.ts
|
@greptile Please re-review head 204e5f1. Repair queries now select only pre-contraction fields, the inbox fixture supplies mandatory Project membership, DDL timeout scopes are explicit, and child stdout is flushed. All 14 affected application integration tests and three focused database tests pass locally. |
|
@cubic-dev-ai review this PR |
@mzxchandra I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
No issues found across 173 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Heads up: you’ve reached your flex budget. Increase your flex budget or wait for usage to reset.
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Turn on auto-fix | Re-trigger cubic
|
@cubic-dev-ai review this PR |
@mzxchandra I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
No issues found across 173 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Heads up: you’ve reached your flex budget. Increase your flex budget or wait for usage to reset.
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Turn on auto-fix | Re-trigger cubic
|
@cubic-dev-ai review this PR |
@mzxchandra I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
No issues found across 175 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Heads up: you’ve reached your flex budget. Increase your flex budget or wait for usage to reset.
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Turn on auto-fix | Re-trigger cubic
|
|
||
| Project APIs return HTTP 503 until the `projects` feature flag is on (AppConfig on hosted deployments; the `PROJECT_API_ENABLED` secret elsewhere). The flag defaults off and gates only the Project APIs: workspace creation always assigns a Project atomically, and assigned Projects keep their lifecycle protections (fork inheritance, disconnect) either way. | ||
|
|
||
| ## Storage and consistency |
There was a problem hiding this comment.
The deleted membership document explained the two-release deployment order, the need to drain old workers, the bounded PostgreSQL table rewrite, and the supported #8830 rollback path. This replacement README describes the final schema but not how to deploy it safely. Operators consulting the repository therefore lose guidance for avoiding an incompatible cutover or rollback.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Summary
Complete the migration to
workspace.project_idafter #8830 is deployed and incompatible membership activity has drained. Release-2 migrations run before application promotion, while release 1 serves traffic.0031_project_membershiprunner switches the checked singleton to column authority under the workspace barrier, then performs bounded, resumable assignment and reconciliation. SQL 0407 remains a placeholder because SQL migrations precede script migrations.workspace.project_id NOT NULLand its restrictive FK, then atomically remove bothproject_workspaceandproject_membership_rollout. The authority-aware feat(projects): move Project membership to the workspace column #8830 runtime remains the supported rollback version after contraction.Permanent enforcement
Replace all custom Project integrity triggers, trigger-specific advisory locks, deferred row-version dispatch, and
UPDATE project SET updated_at = updated_atwith native constraints:personaland IDs asorganization:<id>. The expression always yields a value, cannot be overridden by writers, and supports a composite organization-consistency FK without the nullable-FK loophole.Project non-emptiness and archive lifecycle remain application-owned. Keep existing application Project/lineage/edge/workspace locks and transactional workflow admission. Backfill still validates legacy lifecycle state once; it does not install permanent lifecycle triggers. Keep
project.updated_atas ordinary metadata, and exclude the new internal scope key from Project presentation.Deployment sequence
Migration trade-off and rollback
On PostgreSQL 16/17, adding stored generated columns rewrites the Project/workspace tables. This phase refuses busy tables and bounds each statement to five seconds; a timeout rolls it back before connector removal. This is a bounded blocking operation, not a zero-interruption column addition. Assess table size/capacity before deployment; do not silently extend its lock budget. Interrupted concurrent unique-index builds are repaired on replay.
Use the existing all-at-once traffic cutover and verify the concrete old membership operations/workers have drained. No new maintenance mechanism, dual writes, synchronization triggers, extra compatibility release, or Project-specific PostgreSQL16 CI is introduced. Once authority switches, keep column authority on retries/rollback and never deploy pre-#8830 code. Updated #8830 recognizes the completed schema without the marker, so rollback requires no retained rollout table. Fresh schema push creates no marker; migration replay recognizes completed contraction even when recording its receipt previously failed.
Validation
Focused local checks only; full CI is delegated to GitHub Actions.
Current marker-removal revision: 17 real PostgreSQL checks passed for authority switching, missing-marker refusal, contraction cleanup, failed-receipt replay, and fresh push/replay. The application creation/disconnect/organization-deletion/archive integration case also passed against the migrated database without the marker. DB package type-check, SQL migration safety, schema mock generation, and schema drift checks passed.
Earlier validation for the native-constraint implementation (before marker removal):
Local HTTP proof does not establish production drain completion or external-provider cleanup. GitHub Actions results for the new heads are separate from these local results. Downstream #8609/#8610 still need synchronization. Permanent storage and consistency rules live in
apps/sim/lib/projects/README.md; this PR removespackages/db/PROJECT_MEMBERSHIP.md.Follow-up validation
The review fixes use explicit pre-contraction Project projections (including the name needed by archive responses), update the inbox fixture to create required membership, bound short DDL separately from scans/index builds, and flush child stdout before exit. All 9 operator-repair cases, 5 inbox cases, and 3 focused migration cases passed locally. The existing archive regression failed with the missing name and passed after correction; both reviewed-detach repair cases also passed.
The latest update merges the current staging base through #8830 and consolidates documentation; it changes no application behavior. Both PR diffs were verified unchanged by synchronization before the documentation edit. Full CI and both reviewers rerun on the updated heads; prior results do not establish that these new runs have passed.