docs: staging environment design + implementation plan - #246

Merged
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan
Jul 8, 2026
Merged

docs: staging environment design + implementation plan#246
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan

Conversation

@AndresL230

@AndresL230AndresL230 commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

What

Adds the design spec and a task-by-task implementation plan for an admin-only, fully-hosted staging environment — a parallel mini-prod (Cloudflare Workers frontend + Railway backend + a dedicated Supabase project) where DB migrations and bugfixes can be verified before reaching prod.

Docs only — no code/behavior changes. This PR is the planning artifact; implementation lands in follow-up PRs per the plan's tasks (which is itself a first exercise of the trunk-based workflow the plan defines).

  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
  • docs/superpowers/plans/2026-06-21-staging-environment.md

Key decisions captured

  • Same code, different config. Staging differs from prod only by env vars — no divergent branch to reconcile.
  • Git model: trunk-based. main continuously deploys to staging; a production branch (fast-forwarded from a verified main commit) deploys to prod.
  • Migration runner (Hand-applied migrations have no runner/ordering table — drift hazard #197 — runner already merged on main via its own PR): a ~50-line psycopg-based backend/db/migrate.py over the Supabase direct connection, with a schema_migrations tracking table and ordered migrations/ dir. Also makes migration_cosmetics.sql idempotent (migration_cosmetics.sql adds FK constraints non-idempotently — re-run fails #196).
  • Test data: synthetic seed + deliberately-broken "dirty fixtures" that reproduce backlog failure modes so each fix can be proven.
  • Access control: Cloudflare Access (Zero Trust) on both staging hostnames + noindex; admin email allowlist; service token on the Worker→backend hop.

Backlog this environment de-risks

Migration plumbing (#197, #196); data-integrity migrations (#195, #181, #180, #179); index additions (#178, #177, #176, #161, #160); backend bugs (#158, #168); frontend bugs (#191, #186, #185, #184, #183, #166, #165, #164); prerequisite #163 (dep pinning, tracked separately).

Notes / open questions

  • Share prod Gemini key with staging vs. a separate key.
  • Separate Logfire project for staging vs. mixed traces.
  • Adopting the migration runner against the existing prod DB needs a one-time --baseline run (documented in the plan).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added extensive staging environment design specification and implementation plan documenting a separate, fully-hosted parallel infrastructure stack that mirrors production without sharing live state. Includes trunk-based deployment workflows, access controls, environment configuration, data seeding procedures, security measures (encryption and indexing prevention), and comprehensive operational guidance for staging platform management and pre-production validation testing.

Design spec and task-by-task plan for an admin-only, fully-hosted staging
environment (Cloudflare Workers frontend + Railway backend + dedicated Supabase
project). Includes a psycopg migration runner to close#197, idempotency fix for
#196, trunk-based deploy model, and Cloudflare Access gating. Links the
data-integrity / index / bug backlog the environment de-risks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Jose-Gael-Cruz-Lopez, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 59 minutes and 20 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7118d819-eb67-4c05-9548-7d15cc914ee1

📥 Commits

Reviewing files that changed from the base of the PR and between 06766b8 and 7fe5c14.

📒 Files selected for processing (3)
  • backend/.env.example
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
📝 Walkthrough

Walkthrough

Two new documentation files are added: a design spec (docs/superpowers/specs/2026-06-21-staging-environment-design.md) and a phased implementation plan (docs/superpowers/plans/2026-06-21-staging-environment.md). Together they define an admin-only, fully-hosted staging environment mirroring production via environment variables, a new psycopg-based migration runner, Supabase/Railway/Cloudflare Workers staging setup, and Cloudflare Access gating.

Changes

Staging Environment Documentation

Layer / File(s)Summary
Staging design spec: goals, architecture, and decisions
docs/superpowers/specs/2026-06-21-staging-environment-design.md
Defines isolation rules, v1 goals/non-goals, trunk-based deployment model, Cloudflare Access + noindex decisions, repo change inventory, full architecture (Supabase, Railway, Workers, OAuth, DNS, seed/fixtures, migration runner contract), promotion workflow, phased rollout, backlog enablement mapping, operational risks, and resolved decisions.
Implementation plan: header, constraints, and file map
docs/superpowers/plans/2026-06-21-staging-environment.md
Documents plan title, goal, architecture overview, tech stack, global constraints (DB access paths, encryption rules, secret segregation, dependency pinning), and the complete file-structure outcome map for all new and modified repo artifacts.
Phase 0: psycopg dependency, migration directory, and migrate.py runner
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 1–5: adds psycopg[binary] dependency, reorganizes SQL migrations into a numbered backend/db/migrations/ directory, specifies TDD steps for discover_migrations/pending_migrations pure functions, expands runner with DB tracking table and CLI entrypoint, and makes migration_cosmetics idempotent via DO-block FK guards.
Phase 1: staging Supabase bootstrap, secrets, seed, and dirty fixtures
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 6–8: creates and bootstraps the staging Supabase project via direct connection, generates distinct staging encryption and session secrets, runs a synthetic seed script through PostgREST using encrypt_if_present, and adds dirty_fixtures.sql to reproduce specific backlog failure modes.
Phases 2–3: Google OAuth client and Railway staging environment
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 9 covers creating the Sapling Staging Google OAuth client. Task 10 defines the full Railway staging env-var matrix including distinct Supabase URLs, staging secrets, OAuth credentials, and APP_ENV=staging, plus backend boot verification steps.
Phases 4–5: Cloudflare Workers staging deploy, DNS wiring, and smoke tests
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 11 documents wrangler staging environment configuration and the cf:deploy:staging script. Task 12 covers DNS wiring for staging.saplinglearn.com, api.staging.saplinglearn.com resolution, and the end-to-end smoke test flow including dirty-fixture behavior verification.
Phases 6–7: noindex middleware, Cloudflare Access policies, and trunk-based promotion
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 13 specifies APP_ENV=staging recognition and X-Robots-Tag: noindex, nofollow middleware. Task 14 is the Cloudflare Access operator runbook. Task 15 documents trunk-based deploy wiring, the fast-forward promotion sequence, and self-review notes on baseline caveats and schema reconciliation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • [P1] Set up a staging environment to stop testing on production #100: This PR directly implements the staging environment specification and execution plan described in issue #100, covering the same concepts: separate encryption keys, Cloudflare Access gating, environment-variable configuration, ordered SQL migrations, psycopg migration runner, and phased rollout strategy.

Poem

🐇 Hop, hop through the staging gate,
A mirror of prod — but isolated, great!
Migrations ordered, secrets kept apart,
Cloudflare guards the access with art.
noindex whispers: "search engines, away!"
The rabbit tests safely, then promotes the day. 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe pull request title clearly and concisely summarizes the main change: adding documentation for staging environment design and implementation plan.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description check✅ PassedThe description is detailed and covers purpose, decisions, impact, and open questions, with only minor template heading mismatches.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/staging-environment-plan

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitUpdated (UTC)
❌ Deployment failed
View logs
frontend06766b8Jun 22 2026, 03:56 AM

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (3)
docs/superpowers/plans/2026-06-21-staging-environment.md (2)

270-276: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Minor: Improve the CLI output message grammar.

Line 274's message construction results in "Applied 5 migration(s):" (with a trailing colon) before listing migrations, which is grammatically awkward. Consider simplifying to match typical CLI patterns:

🔧 Suggested revision
- verb = "Baselined" if baseline else "Applied"- print(f"{verb} {len(handled)} migration(s):" if handled else "No pending migrations.")- for name in handled:- print(f" - {name}")+ if handled:+ verb = "Baselined" if baseline else "Applied"+ print(f"{verb} {len(handled)} migration(s).")+ for name in handled:+ print(f" - {name}")+ else:+ print("No pending migrations.")

This separates the summary line from the list and removes the trailing colon.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 270 -
276, The print statement that constructs the migration summary message has a
grammatically awkward trailing colon in the output when migrations are handled.
Modify the conditional print statement to remove the trailing colon from the
migration count message, ensuring the summary line is cleanly separated from the
list of migration names that follows on subsequent lines.

31-38: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add explicit step to update .env.example.

The file structure lists backend/.env.example as modified (to document SUPABASE_DB_URL and APP_ENV=staging), but no task explicitly covers this update. Consider adding a step in Task 1 (psycopg dependency) or creating a standalone "documentation" sub-task to ensure this is not overlooked.

💡 Suggested addition to Task 1, Step 3 (before commit)
-[ ]**Step 2.5: Update `.env.example`** (if not already documented)
Run: `grep -q "SUPABASE_DB_URL" backend/.env.example || echo "SUPABASE_DB_URL=postgresql://..." >> backend/.env.example`
Ensure the file documents both `SUPABASE_DB_URL` (for migration runner) and `APP_ENV=staging` as examples.

Then update the existing Step 3 commit message to reference .env.example:

git add backend/requirements.txt backend/.env.example
git commit -m "build: add psycopg dependency + document SUPABASE_DB_URL in .env.example (`#197`)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 31 -
38, The staging environment plan lists backend/.env.example as a modified file
in the file structure section but does not include an explicit task step that
covers updating it with the new SUPABASE_DB_URL and APP_ENV=staging
documentation. Add a new sub-task step (such as Step 2.5 under Task 1) that
explicitly instructs to update backend/.env.example to document both
SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
docs/superpowers/specs/2026-06-21-staging-environment-design.md (1)

212-221: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Vary sentence structure in the phases list to improve readability.

Lines 216–221 have repetitive sentence beginnings ("Phase X"), which LanguageTool flagged. While this structure is functional, consider alternating phrasing to improve prose flow. For example:

  • "Phase 0 — migration runner + ordered/idempotent migrations" (current)
  • "Bring the migration runner and ordered/idempotent migrations online (Phase 0)" (alternative)

This is a low-priority style suggestion; the current form is acceptable for a checklist-style outline.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md` around lines
212 - 221, The phases list in the Build phases section (Phase 0 through Phase 7)
has repetitive sentence structure where every item begins with "**Phase X** —"
which reduces readability. To fix this, vary the phrasing of some items by
restructuring them with different sentence beginnings while preserving the phase
numbers and core content. For example, some items could reorder the phase
reference to the end in parentheses (like "Set up X (Phase Y)"), while others
could keep the original format, creating an alternating pattern that improves
prose flow without losing the checklist clarity or changing the actual
deliverables described in each phase.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@docs/superpowers/plans/2026-06-21-staging-environment.md`:
- Around line 270-276: The print statement that constructs the migration summary
message has a grammatically awkward trailing colon in the output when migrations
are handled. Modify the conditional print statement to remove the trailing colon
from the migration count message, ensuring the summary line is cleanly separated
from the list of migration names that follows on subsequent lines.
- Around line 31-38: The staging environment plan lists backend/.env.example as
a modified file in the file structure section but does not include an explicit
task step that covers updating it with the new SUPABASE_DB_URL and
APP_ENV=staging documentation. Add a new sub-task step (such as Step 2.5 under
Task 1) that explicitly instructs to update backend/.env.example to document
both SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md`:
- Around line 212-221: The phases list in the Build phases section (Phase 0
through Phase 7) has repetitive sentence structure where every item begins with
"**Phase X** —" which reduces readability. To fix this, vary the phrasing of
some items by restructuring them with different sentence beginnings while
preserving the phase numbers and core content. For example, some items could
reorder the phase reference to the end in parentheses (like "Set up X (Phase
Y)"), while others could keep the original format, creating an alternating
pattern that improves prose flow without losing the checklist clarity or
changing the actual deliverables described in each phase.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f8b34cd0-702f-473a-981d-26c4f89dfb86

📥 Commits

Reviewing files that changed from the base of the PR and between 4521305 and 06766b8.

📒 Files selected for processing (2)
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Jun 24, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7fe5c14Commit Preview URL

Branch Preview URL
Jun 24 2026, 02:34 PM

@AndresL230
AndresL230 merged commit e887251 into mainJul 8, 2026
6 checks passed
@AndresL230
AndresL230 deleted the docs/staging-environment-plan branch August 2, 2026 18:29
Sign up for freeto 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

@AndresL230@Jose-Gael-Cruz-Lopez
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

docs: staging environment design + implementation plan - #246

Merged
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan
Jul 8, 2026
Merged

docs: staging environment design + implementation plan#246
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan

Conversation

@AndresL230

@AndresL230AndresL230 commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

What

Adds the design spec and a task-by-task implementation plan for an admin-only, fully-hosted staging environment — a parallel mini-prod (Cloudflare Workers frontend + Railway backend + a dedicated Supabase project) where DB migrations and bugfixes can be verified before reaching prod.

Docs only — no code/behavior changes. This PR is the planning artifact; implementation lands in follow-up PRs per the plan's tasks (which is itself a first exercise of the trunk-based workflow the plan defines).

  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
  • docs/superpowers/plans/2026-06-21-staging-environment.md

Key decisions captured

  • Same code, different config. Staging differs from prod only by env vars — no divergent branch to reconcile.
  • Git model: trunk-based. main continuously deploys to staging; a production branch (fast-forwarded from a verified main commit) deploys to prod.
  • Migration runner (Hand-applied migrations have no runner/ordering table — drift hazard #197 — runner already merged on main via its own PR): a ~50-line psycopg-based backend/db/migrate.py over the Supabase direct connection, with a schema_migrations tracking table and ordered migrations/ dir. Also makes migration_cosmetics.sql idempotent (migration_cosmetics.sql adds FK constraints non-idempotently — re-run fails #196).
  • Test data: synthetic seed + deliberately-broken "dirty fixtures" that reproduce backlog failure modes so each fix can be proven.
  • Access control: Cloudflare Access (Zero Trust) on both staging hostnames + noindex; admin email allowlist; service token on the Worker→backend hop.

Backlog this environment de-risks

Migration plumbing (#197, #196); data-integrity migrations (#195, #181, #180, #179); index additions (#178, #177, #176, #161, #160); backend bugs (#158, #168); frontend bugs (#191, #186, #185, #184, #183, #166, #165, #164); prerequisite #163 (dep pinning, tracked separately).

Notes / open questions

  • Share prod Gemini key with staging vs. a separate key.
  • Separate Logfire project for staging vs. mixed traces.
  • Adopting the migration runner against the existing prod DB needs a one-time --baseline run (documented in the plan).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added extensive staging environment design specification and implementation plan documenting a separate, fully-hosted parallel infrastructure stack that mirrors production without sharing live state. Includes trunk-based deployment workflows, access controls, environment configuration, data seeding procedures, security measures (encryption and indexing prevention), and comprehensive operational guidance for staging platform management and pre-production validation testing.

Design spec and task-by-task plan for an admin-only, fully-hosted staging
environment (Cloudflare Workers frontend + Railway backend + dedicated Supabase
project). Includes a psycopg migration runner to close#197, idempotency fix for
#196, trunk-based deploy model, and Cloudflare Access gating. Links the
data-integrity / index / bug backlog the environment de-risks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Jose-Gael-Cruz-Lopez, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 59 minutes and 20 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7118d819-eb67-4c05-9548-7d15cc914ee1

📥 Commits

Reviewing files that changed from the base of the PR and between 06766b8 and 7fe5c14.

📒 Files selected for processing (3)
  • backend/.env.example
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
📝 Walkthrough

Walkthrough

Two new documentation files are added: a design spec (docs/superpowers/specs/2026-06-21-staging-environment-design.md) and a phased implementation plan (docs/superpowers/plans/2026-06-21-staging-environment.md). Together they define an admin-only, fully-hosted staging environment mirroring production via environment variables, a new psycopg-based migration runner, Supabase/Railway/Cloudflare Workers staging setup, and Cloudflare Access gating.

Changes

Staging Environment Documentation

Layer / File(s)Summary
Staging design spec: goals, architecture, and decisions
docs/superpowers/specs/2026-06-21-staging-environment-design.md
Defines isolation rules, v1 goals/non-goals, trunk-based deployment model, Cloudflare Access + noindex decisions, repo change inventory, full architecture (Supabase, Railway, Workers, OAuth, DNS, seed/fixtures, migration runner contract), promotion workflow, phased rollout, backlog enablement mapping, operational risks, and resolved decisions.
Implementation plan: header, constraints, and file map
docs/superpowers/plans/2026-06-21-staging-environment.md
Documents plan title, goal, architecture overview, tech stack, global constraints (DB access paths, encryption rules, secret segregation, dependency pinning), and the complete file-structure outcome map for all new and modified repo artifacts.
Phase 0: psycopg dependency, migration directory, and migrate.py runner
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 1–5: adds psycopg[binary] dependency, reorganizes SQL migrations into a numbered backend/db/migrations/ directory, specifies TDD steps for discover_migrations/pending_migrations pure functions, expands runner with DB tracking table and CLI entrypoint, and makes migration_cosmetics idempotent via DO-block FK guards.
Phase 1: staging Supabase bootstrap, secrets, seed, and dirty fixtures
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 6–8: creates and bootstraps the staging Supabase project via direct connection, generates distinct staging encryption and session secrets, runs a synthetic seed script through PostgREST using encrypt_if_present, and adds dirty_fixtures.sql to reproduce specific backlog failure modes.
Phases 2–3: Google OAuth client and Railway staging environment
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 9 covers creating the Sapling Staging Google OAuth client. Task 10 defines the full Railway staging env-var matrix including distinct Supabase URLs, staging secrets, OAuth credentials, and APP_ENV=staging, plus backend boot verification steps.
Phases 4–5: Cloudflare Workers staging deploy, DNS wiring, and smoke tests
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 11 documents wrangler staging environment configuration and the cf:deploy:staging script. Task 12 covers DNS wiring for staging.saplinglearn.com, api.staging.saplinglearn.com resolution, and the end-to-end smoke test flow including dirty-fixture behavior verification.
Phases 6–7: noindex middleware, Cloudflare Access policies, and trunk-based promotion
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 13 specifies APP_ENV=staging recognition and X-Robots-Tag: noindex, nofollow middleware. Task 14 is the Cloudflare Access operator runbook. Task 15 documents trunk-based deploy wiring, the fast-forward promotion sequence, and self-review notes on baseline caveats and schema reconciliation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • [P1] Set up a staging environment to stop testing on production #100: This PR directly implements the staging environment specification and execution plan described in issue #100, covering the same concepts: separate encryption keys, Cloudflare Access gating, environment-variable configuration, ordered SQL migrations, psycopg migration runner, and phased rollout strategy.

Poem

🐇 Hop, hop through the staging gate,
A mirror of prod — but isolated, great!
Migrations ordered, secrets kept apart,
Cloudflare guards the access with art.
noindex whispers: "search engines, away!"
The rabbit tests safely, then promotes the day. 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe pull request title clearly and concisely summarizes the main change: adding documentation for staging environment design and implementation plan.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description check✅ PassedThe description is detailed and covers purpose, decisions, impact, and open questions, with only minor template heading mismatches.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/staging-environment-plan

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitUpdated (UTC)
❌ Deployment failed
View logs
frontend06766b8Jun 22 2026, 03:56 AM

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (3)
docs/superpowers/plans/2026-06-21-staging-environment.md (2)

270-276: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Minor: Improve the CLI output message grammar.

Line 274's message construction results in "Applied 5 migration(s):" (with a trailing colon) before listing migrations, which is grammatically awkward. Consider simplifying to match typical CLI patterns:

🔧 Suggested revision
- verb = "Baselined" if baseline else "Applied"- print(f"{verb} {len(handled)} migration(s):" if handled else "No pending migrations.")- for name in handled:- print(f" - {name}")+ if handled:+ verb = "Baselined" if baseline else "Applied"+ print(f"{verb} {len(handled)} migration(s).")+ for name in handled:+ print(f" - {name}")+ else:+ print("No pending migrations.")

This separates the summary line from the list and removes the trailing colon.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 270 -
276, The print statement that constructs the migration summary message has a
grammatically awkward trailing colon in the output when migrations are handled.
Modify the conditional print statement to remove the trailing colon from the
migration count message, ensuring the summary line is cleanly separated from the
list of migration names that follows on subsequent lines.

31-38: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add explicit step to update .env.example.

The file structure lists backend/.env.example as modified (to document SUPABASE_DB_URL and APP_ENV=staging), but no task explicitly covers this update. Consider adding a step in Task 1 (psycopg dependency) or creating a standalone "documentation" sub-task to ensure this is not overlooked.

💡 Suggested addition to Task 1, Step 3 (before commit)
-[ ]**Step 2.5: Update `.env.example`** (if not already documented)
Run: `grep -q "SUPABASE_DB_URL" backend/.env.example || echo "SUPABASE_DB_URL=postgresql://..." >> backend/.env.example`
Ensure the file documents both `SUPABASE_DB_URL` (for migration runner) and `APP_ENV=staging` as examples.

Then update the existing Step 3 commit message to reference .env.example:

git add backend/requirements.txt backend/.env.example
git commit -m "build: add psycopg dependency + document SUPABASE_DB_URL in .env.example (`#197`)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 31 -
38, The staging environment plan lists backend/.env.example as a modified file
in the file structure section but does not include an explicit task step that
covers updating it with the new SUPABASE_DB_URL and APP_ENV=staging
documentation. Add a new sub-task step (such as Step 2.5 under Task 1) that
explicitly instructs to update backend/.env.example to document both
SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
docs/superpowers/specs/2026-06-21-staging-environment-design.md (1)

212-221: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Vary sentence structure in the phases list to improve readability.

Lines 216–221 have repetitive sentence beginnings ("Phase X"), which LanguageTool flagged. While this structure is functional, consider alternating phrasing to improve prose flow. For example:

  • "Phase 0 — migration runner + ordered/idempotent migrations" (current)
  • "Bring the migration runner and ordered/idempotent migrations online (Phase 0)" (alternative)

This is a low-priority style suggestion; the current form is acceptable for a checklist-style outline.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md` around lines
212 - 221, The phases list in the Build phases section (Phase 0 through Phase 7)
has repetitive sentence structure where every item begins with "**Phase X** —"
which reduces readability. To fix this, vary the phrasing of some items by
restructuring them with different sentence beginnings while preserving the phase
numbers and core content. For example, some items could reorder the phase
reference to the end in parentheses (like "Set up X (Phase Y)"), while others
could keep the original format, creating an alternating pattern that improves
prose flow without losing the checklist clarity or changing the actual
deliverables described in each phase.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@docs/superpowers/plans/2026-06-21-staging-environment.md`:
- Around line 270-276: The print statement that constructs the migration summary
message has a grammatically awkward trailing colon in the output when migrations
are handled. Modify the conditional print statement to remove the trailing colon
from the migration count message, ensuring the summary line is cleanly separated
from the list of migration names that follows on subsequent lines.
- Around line 31-38: The staging environment plan lists backend/.env.example as
a modified file in the file structure section but does not include an explicit
task step that covers updating it with the new SUPABASE_DB_URL and
APP_ENV=staging documentation. Add a new sub-task step (such as Step 2.5 under
Task 1) that explicitly instructs to update backend/.env.example to document
both SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md`:
- Around line 212-221: The phases list in the Build phases section (Phase 0
through Phase 7) has repetitive sentence structure where every item begins with
"**Phase X** —" which reduces readability. To fix this, vary the phrasing of
some items by restructuring them with different sentence beginnings while
preserving the phase numbers and core content. For example, some items could
reorder the phase reference to the end in parentheses (like "Set up X (Phase
Y)"), while others could keep the original format, creating an alternating
pattern that improves prose flow without losing the checklist clarity or
changing the actual deliverables described in each phase.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f8b34cd0-702f-473a-981d-26c4f89dfb86

📥 Commits

Reviewing files that changed from the base of the PR and between 4521305 and 06766b8.

📒 Files selected for processing (2)
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Jun 24, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7fe5c14Commit Preview URL

Branch Preview URL
Jun 24 2026, 02:34 PM

@AndresL230
AndresL230 merged commit e887251 into mainJul 8, 2026
6 checks passed
@AndresL230
AndresL230 deleted the docs/staging-environment-plan branch August 2, 2026 18:29
Sign up for freeto 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

@AndresL230@Jose-Gael-Cruz-Lopez
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs: staging environment design + implementation plan - #246

Merged
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan
Jul 8, 2026
Merged

docs: staging environment design + implementation plan#246
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan

Conversation

@AndresL230

@AndresL230AndresL230 commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

What

Adds the design spec and a task-by-task implementation plan for an admin-only, fully-hosted staging environment — a parallel mini-prod (Cloudflare Workers frontend + Railway backend + a dedicated Supabase project) where DB migrations and bugfixes can be verified before reaching prod.

Docs only — no code/behavior changes. This PR is the planning artifact; implementation lands in follow-up PRs per the plan's tasks (which is itself a first exercise of the trunk-based workflow the plan defines).

  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
  • docs/superpowers/plans/2026-06-21-staging-environment.md

Key decisions captured

  • Same code, different config. Staging differs from prod only by env vars — no divergent branch to reconcile.
  • Git model: trunk-based. main continuously deploys to staging; a production branch (fast-forwarded from a verified main commit) deploys to prod.
  • Migration runner (Hand-applied migrations have no runner/ordering table — drift hazard #197 — runner already merged on main via its own PR): a ~50-line psycopg-based backend/db/migrate.py over the Supabase direct connection, with a schema_migrations tracking table and ordered migrations/ dir. Also makes migration_cosmetics.sql idempotent (migration_cosmetics.sql adds FK constraints non-idempotently — re-run fails #196).
  • Test data: synthetic seed + deliberately-broken "dirty fixtures" that reproduce backlog failure modes so each fix can be proven.
  • Access control: Cloudflare Access (Zero Trust) on both staging hostnames + noindex; admin email allowlist; service token on the Worker→backend hop.

Backlog this environment de-risks

Migration plumbing (#197, #196); data-integrity migrations (#195, #181, #180, #179); index additions (#178, #177, #176, #161, #160); backend bugs (#158, #168); frontend bugs (#191, #186, #185, #184, #183, #166, #165, #164); prerequisite #163 (dep pinning, tracked separately).

Notes / open questions

  • Share prod Gemini key with staging vs. a separate key.
  • Separate Logfire project for staging vs. mixed traces.
  • Adopting the migration runner against the existing prod DB needs a one-time --baseline run (documented in the plan).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added extensive staging environment design specification and implementation plan documenting a separate, fully-hosted parallel infrastructure stack that mirrors production without sharing live state. Includes trunk-based deployment workflows, access controls, environment configuration, data seeding procedures, security measures (encryption and indexing prevention), and comprehensive operational guidance for staging platform management and pre-production validation testing.

Design spec and task-by-task plan for an admin-only, fully-hosted staging
environment (Cloudflare Workers frontend + Railway backend + dedicated Supabase
project). Includes a psycopg migration runner to close#197, idempotency fix for
#196, trunk-based deploy model, and Cloudflare Access gating. Links the
data-integrity / index / bug backlog the environment de-risks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Jose-Gael-Cruz-Lopez, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 59 minutes and 20 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7118d819-eb67-4c05-9548-7d15cc914ee1

📥 Commits

Reviewing files that changed from the base of the PR and between 06766b8 and 7fe5c14.

📒 Files selected for processing (3)
  • backend/.env.example
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
📝 Walkthrough

Walkthrough

Two new documentation files are added: a design spec (docs/superpowers/specs/2026-06-21-staging-environment-design.md) and a phased implementation plan (docs/superpowers/plans/2026-06-21-staging-environment.md). Together they define an admin-only, fully-hosted staging environment mirroring production via environment variables, a new psycopg-based migration runner, Supabase/Railway/Cloudflare Workers staging setup, and Cloudflare Access gating.

Changes

Staging Environment Documentation

Layer / File(s)Summary
Staging design spec: goals, architecture, and decisions
docs/superpowers/specs/2026-06-21-staging-environment-design.md
Defines isolation rules, v1 goals/non-goals, trunk-based deployment model, Cloudflare Access + noindex decisions, repo change inventory, full architecture (Supabase, Railway, Workers, OAuth, DNS, seed/fixtures, migration runner contract), promotion workflow, phased rollout, backlog enablement mapping, operational risks, and resolved decisions.
Implementation plan: header, constraints, and file map
docs/superpowers/plans/2026-06-21-staging-environment.md
Documents plan title, goal, architecture overview, tech stack, global constraints (DB access paths, encryption rules, secret segregation, dependency pinning), and the complete file-structure outcome map for all new and modified repo artifacts.
Phase 0: psycopg dependency, migration directory, and migrate.py runner
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 1–5: adds psycopg[binary] dependency, reorganizes SQL migrations into a numbered backend/db/migrations/ directory, specifies TDD steps for discover_migrations/pending_migrations pure functions, expands runner with DB tracking table and CLI entrypoint, and makes migration_cosmetics idempotent via DO-block FK guards.
Phase 1: staging Supabase bootstrap, secrets, seed, and dirty fixtures
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 6–8: creates and bootstraps the staging Supabase project via direct connection, generates distinct staging encryption and session secrets, runs a synthetic seed script through PostgREST using encrypt_if_present, and adds dirty_fixtures.sql to reproduce specific backlog failure modes.
Phases 2–3: Google OAuth client and Railway staging environment
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 9 covers creating the Sapling Staging Google OAuth client. Task 10 defines the full Railway staging env-var matrix including distinct Supabase URLs, staging secrets, OAuth credentials, and APP_ENV=staging, plus backend boot verification steps.
Phases 4–5: Cloudflare Workers staging deploy, DNS wiring, and smoke tests
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 11 documents wrangler staging environment configuration and the cf:deploy:staging script. Task 12 covers DNS wiring for staging.saplinglearn.com, api.staging.saplinglearn.com resolution, and the end-to-end smoke test flow including dirty-fixture behavior verification.
Phases 6–7: noindex middleware, Cloudflare Access policies, and trunk-based promotion
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 13 specifies APP_ENV=staging recognition and X-Robots-Tag: noindex, nofollow middleware. Task 14 is the Cloudflare Access operator runbook. Task 15 documents trunk-based deploy wiring, the fast-forward promotion sequence, and self-review notes on baseline caveats and schema reconciliation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • [P1] Set up a staging environment to stop testing on production #100: This PR directly implements the staging environment specification and execution plan described in issue #100, covering the same concepts: separate encryption keys, Cloudflare Access gating, environment-variable configuration, ordered SQL migrations, psycopg migration runner, and phased rollout strategy.

Poem

🐇 Hop, hop through the staging gate,
A mirror of prod — but isolated, great!
Migrations ordered, secrets kept apart,
Cloudflare guards the access with art.
noindex whispers: "search engines, away!"
The rabbit tests safely, then promotes the day. 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe pull request title clearly and concisely summarizes the main change: adding documentation for staging environment design and implementation plan.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description check✅ PassedThe description is detailed and covers purpose, decisions, impact, and open questions, with only minor template heading mismatches.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/staging-environment-plan

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitUpdated (UTC)
❌ Deployment failed
View logs
frontend06766b8Jun 22 2026, 03:56 AM

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (3)
docs/superpowers/plans/2026-06-21-staging-environment.md (2)

270-276: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Minor: Improve the CLI output message grammar.

Line 274's message construction results in "Applied 5 migration(s):" (with a trailing colon) before listing migrations, which is grammatically awkward. Consider simplifying to match typical CLI patterns:

🔧 Suggested revision
- verb = "Baselined" if baseline else "Applied"- print(f"{verb} {len(handled)} migration(s):" if handled else "No pending migrations.")- for name in handled:- print(f" - {name}")+ if handled:+ verb = "Baselined" if baseline else "Applied"+ print(f"{verb} {len(handled)} migration(s).")+ for name in handled:+ print(f" - {name}")+ else:+ print("No pending migrations.")

This separates the summary line from the list and removes the trailing colon.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 270 -
276, The print statement that constructs the migration summary message has a
grammatically awkward trailing colon in the output when migrations are handled.
Modify the conditional print statement to remove the trailing colon from the
migration count message, ensuring the summary line is cleanly separated from the
list of migration names that follows on subsequent lines.

31-38: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add explicit step to update .env.example.

The file structure lists backend/.env.example as modified (to document SUPABASE_DB_URL and APP_ENV=staging), but no task explicitly covers this update. Consider adding a step in Task 1 (psycopg dependency) or creating a standalone "documentation" sub-task to ensure this is not overlooked.

💡 Suggested addition to Task 1, Step 3 (before commit)
-[ ]**Step 2.5: Update `.env.example`** (if not already documented)
Run: `grep -q "SUPABASE_DB_URL" backend/.env.example || echo "SUPABASE_DB_URL=postgresql://..." >> backend/.env.example`
Ensure the file documents both `SUPABASE_DB_URL` (for migration runner) and `APP_ENV=staging` as examples.

Then update the existing Step 3 commit message to reference .env.example:

git add backend/requirements.txt backend/.env.example
git commit -m "build: add psycopg dependency + document SUPABASE_DB_URL in .env.example (`#197`)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 31 -
38, The staging environment plan lists backend/.env.example as a modified file
in the file structure section but does not include an explicit task step that
covers updating it with the new SUPABASE_DB_URL and APP_ENV=staging
documentation. Add a new sub-task step (such as Step 2.5 under Task 1) that
explicitly instructs to update backend/.env.example to document both
SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
docs/superpowers/specs/2026-06-21-staging-environment-design.md (1)

212-221: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Vary sentence structure in the phases list to improve readability.

Lines 216–221 have repetitive sentence beginnings ("Phase X"), which LanguageTool flagged. While this structure is functional, consider alternating phrasing to improve prose flow. For example:

  • "Phase 0 — migration runner + ordered/idempotent migrations" (current)
  • "Bring the migration runner and ordered/idempotent migrations online (Phase 0)" (alternative)

This is a low-priority style suggestion; the current form is acceptable for a checklist-style outline.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md` around lines
212 - 221, The phases list in the Build phases section (Phase 0 through Phase 7)
has repetitive sentence structure where every item begins with "**Phase X** —"
which reduces readability. To fix this, vary the phrasing of some items by
restructuring them with different sentence beginnings while preserving the phase
numbers and core content. For example, some items could reorder the phase
reference to the end in parentheses (like "Set up X (Phase Y)"), while others
could keep the original format, creating an alternating pattern that improves
prose flow without losing the checklist clarity or changing the actual
deliverables described in each phase.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@docs/superpowers/plans/2026-06-21-staging-environment.md`:
- Around line 270-276: The print statement that constructs the migration summary
message has a grammatically awkward trailing colon in the output when migrations
are handled. Modify the conditional print statement to remove the trailing colon
from the migration count message, ensuring the summary line is cleanly separated
from the list of migration names that follows on subsequent lines.
- Around line 31-38: The staging environment plan lists backend/.env.example as
a modified file in the file structure section but does not include an explicit
task step that covers updating it with the new SUPABASE_DB_URL and
APP_ENV=staging documentation. Add a new sub-task step (such as Step 2.5 under
Task 1) that explicitly instructs to update backend/.env.example to document
both SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md`:
- Around line 212-221: The phases list in the Build phases section (Phase 0
through Phase 7) has repetitive sentence structure where every item begins with
"**Phase X** —" which reduces readability. To fix this, vary the phrasing of
some items by restructuring them with different sentence beginnings while
preserving the phase numbers and core content. For example, some items could
reorder the phase reference to the end in parentheses (like "Set up X (Phase
Y)"), while others could keep the original format, creating an alternating
pattern that improves prose flow without losing the checklist clarity or
changing the actual deliverables described in each phase.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f8b34cd0-702f-473a-981d-26c4f89dfb86

📥 Commits

Reviewing files that changed from the base of the PR and between 4521305 and 06766b8.

📒 Files selected for processing (2)
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Jun 24, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7fe5c14Commit Preview URL

Branch Preview URL
Jun 24 2026, 02:34 PM

@AndresL230
AndresL230 merged commit e887251 into mainJul 8, 2026
6 checks passed
@AndresL230
AndresL230 deleted the docs/staging-environment-plan branch August 2, 2026 18:29
Sign up for freeto 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

@AndresL230@Jose-Gael-Cruz-Lopez
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs: staging environment design + implementation plan - #246

Merged
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan
Jul 8, 2026
Merged

docs: staging environment design + implementation plan#246
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan

Conversation

@AndresL230

@AndresL230AndresL230 commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

What

Adds the design spec and a task-by-task implementation plan for an admin-only, fully-hosted staging environment — a parallel mini-prod (Cloudflare Workers frontend + Railway backend + a dedicated Supabase project) where DB migrations and bugfixes can be verified before reaching prod.

Docs only — no code/behavior changes. This PR is the planning artifact; implementation lands in follow-up PRs per the plan's tasks (which is itself a first exercise of the trunk-based workflow the plan defines).

  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
  • docs/superpowers/plans/2026-06-21-staging-environment.md

Key decisions captured

  • Same code, different config. Staging differs from prod only by env vars — no divergent branch to reconcile.
  • Git model: trunk-based. main continuously deploys to staging; a production branch (fast-forwarded from a verified main commit) deploys to prod.
  • Migration runner (Hand-applied migrations have no runner/ordering table — drift hazard #197 — runner already merged on main via its own PR): a ~50-line psycopg-based backend/db/migrate.py over the Supabase direct connection, with a schema_migrations tracking table and ordered migrations/ dir. Also makes migration_cosmetics.sql idempotent (migration_cosmetics.sql adds FK constraints non-idempotently — re-run fails #196).
  • Test data: synthetic seed + deliberately-broken "dirty fixtures" that reproduce backlog failure modes so each fix can be proven.
  • Access control: Cloudflare Access (Zero Trust) on both staging hostnames + noindex; admin email allowlist; service token on the Worker→backend hop.

Backlog this environment de-risks

Migration plumbing (#197, #196); data-integrity migrations (#195, #181, #180, #179); index additions (#178, #177, #176, #161, #160); backend bugs (#158, #168); frontend bugs (#191, #186, #185, #184, #183, #166, #165, #164); prerequisite #163 (dep pinning, tracked separately).

Notes / open questions

  • Share prod Gemini key with staging vs. a separate key.
  • Separate Logfire project for staging vs. mixed traces.
  • Adopting the migration runner against the existing prod DB needs a one-time --baseline run (documented in the plan).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added extensive staging environment design specification and implementation plan documenting a separate, fully-hosted parallel infrastructure stack that mirrors production without sharing live state. Includes trunk-based deployment workflows, access controls, environment configuration, data seeding procedures, security measures (encryption and indexing prevention), and comprehensive operational guidance for staging platform management and pre-production validation testing.

Design spec and task-by-task plan for an admin-only, fully-hosted staging
environment (Cloudflare Workers frontend + Railway backend + dedicated Supabase
project). Includes a psycopg migration runner to close#197, idempotency fix for
#196, trunk-based deploy model, and Cloudflare Access gating. Links the
data-integrity / index / bug backlog the environment de-risks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Jose-Gael-Cruz-Lopez, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 59 minutes and 20 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7118d819-eb67-4c05-9548-7d15cc914ee1

📥 Commits

Reviewing files that changed from the base of the PR and between 06766b8 and 7fe5c14.

📒 Files selected for processing (3)
  • backend/.env.example
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
📝 Walkthrough

Walkthrough

Two new documentation files are added: a design spec (docs/superpowers/specs/2026-06-21-staging-environment-design.md) and a phased implementation plan (docs/superpowers/plans/2026-06-21-staging-environment.md). Together they define an admin-only, fully-hosted staging environment mirroring production via environment variables, a new psycopg-based migration runner, Supabase/Railway/Cloudflare Workers staging setup, and Cloudflare Access gating.

Changes

Staging Environment Documentation

Layer / File(s)Summary
Staging design spec: goals, architecture, and decisions
docs/superpowers/specs/2026-06-21-staging-environment-design.md
Defines isolation rules, v1 goals/non-goals, trunk-based deployment model, Cloudflare Access + noindex decisions, repo change inventory, full architecture (Supabase, Railway, Workers, OAuth, DNS, seed/fixtures, migration runner contract), promotion workflow, phased rollout, backlog enablement mapping, operational risks, and resolved decisions.
Implementation plan: header, constraints, and file map
docs/superpowers/plans/2026-06-21-staging-environment.md
Documents plan title, goal, architecture overview, tech stack, global constraints (DB access paths, encryption rules, secret segregation, dependency pinning), and the complete file-structure outcome map for all new and modified repo artifacts.
Phase 0: psycopg dependency, migration directory, and migrate.py runner
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 1–5: adds psycopg[binary] dependency, reorganizes SQL migrations into a numbered backend/db/migrations/ directory, specifies TDD steps for discover_migrations/pending_migrations pure functions, expands runner with DB tracking table and CLI entrypoint, and makes migration_cosmetics idempotent via DO-block FK guards.
Phase 1: staging Supabase bootstrap, secrets, seed, and dirty fixtures
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 6–8: creates and bootstraps the staging Supabase project via direct connection, generates distinct staging encryption and session secrets, runs a synthetic seed script through PostgREST using encrypt_if_present, and adds dirty_fixtures.sql to reproduce specific backlog failure modes.
Phases 2–3: Google OAuth client and Railway staging environment
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 9 covers creating the Sapling Staging Google OAuth client. Task 10 defines the full Railway staging env-var matrix including distinct Supabase URLs, staging secrets, OAuth credentials, and APP_ENV=staging, plus backend boot verification steps.
Phases 4–5: Cloudflare Workers staging deploy, DNS wiring, and smoke tests
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 11 documents wrangler staging environment configuration and the cf:deploy:staging script. Task 12 covers DNS wiring for staging.saplinglearn.com, api.staging.saplinglearn.com resolution, and the end-to-end smoke test flow including dirty-fixture behavior verification.
Phases 6–7: noindex middleware, Cloudflare Access policies, and trunk-based promotion
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 13 specifies APP_ENV=staging recognition and X-Robots-Tag: noindex, nofollow middleware. Task 14 is the Cloudflare Access operator runbook. Task 15 documents trunk-based deploy wiring, the fast-forward promotion sequence, and self-review notes on baseline caveats and schema reconciliation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • [P1] Set up a staging environment to stop testing on production #100: This PR directly implements the staging environment specification and execution plan described in issue #100, covering the same concepts: separate encryption keys, Cloudflare Access gating, environment-variable configuration, ordered SQL migrations, psycopg migration runner, and phased rollout strategy.

Poem

🐇 Hop, hop through the staging gate,
A mirror of prod — but isolated, great!
Migrations ordered, secrets kept apart,
Cloudflare guards the access with art.
noindex whispers: "search engines, away!"
The rabbit tests safely, then promotes the day. 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe pull request title clearly and concisely summarizes the main change: adding documentation for staging environment design and implementation plan.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description check✅ PassedThe description is detailed and covers purpose, decisions, impact, and open questions, with only minor template heading mismatches.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/staging-environment-plan

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitUpdated (UTC)
❌ Deployment failed
View logs
frontend06766b8Jun 22 2026, 03:56 AM

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (3)
docs/superpowers/plans/2026-06-21-staging-environment.md (2)

270-276: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Minor: Improve the CLI output message grammar.

Line 274's message construction results in "Applied 5 migration(s):" (with a trailing colon) before listing migrations, which is grammatically awkward. Consider simplifying to match typical CLI patterns:

🔧 Suggested revision
- verb = "Baselined" if baseline else "Applied"- print(f"{verb} {len(handled)} migration(s):" if handled else "No pending migrations.")- for name in handled:- print(f" - {name}")+ if handled:+ verb = "Baselined" if baseline else "Applied"+ print(f"{verb} {len(handled)} migration(s).")+ for name in handled:+ print(f" - {name}")+ else:+ print("No pending migrations.")

This separates the summary line from the list and removes the trailing colon.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 270 -
276, The print statement that constructs the migration summary message has a
grammatically awkward trailing colon in the output when migrations are handled.
Modify the conditional print statement to remove the trailing colon from the
migration count message, ensuring the summary line is cleanly separated from the
list of migration names that follows on subsequent lines.

31-38: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add explicit step to update .env.example.

The file structure lists backend/.env.example as modified (to document SUPABASE_DB_URL and APP_ENV=staging), but no task explicitly covers this update. Consider adding a step in Task 1 (psycopg dependency) or creating a standalone "documentation" sub-task to ensure this is not overlooked.

💡 Suggested addition to Task 1, Step 3 (before commit)
-[ ]**Step 2.5: Update `.env.example`** (if not already documented)
Run: `grep -q "SUPABASE_DB_URL" backend/.env.example || echo "SUPABASE_DB_URL=postgresql://..." >> backend/.env.example`
Ensure the file documents both `SUPABASE_DB_URL` (for migration runner) and `APP_ENV=staging` as examples.

Then update the existing Step 3 commit message to reference .env.example:

git add backend/requirements.txt backend/.env.example
git commit -m "build: add psycopg dependency + document SUPABASE_DB_URL in .env.example (`#197`)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 31 -
38, The staging environment plan lists backend/.env.example as a modified file
in the file structure section but does not include an explicit task step that
covers updating it with the new SUPABASE_DB_URL and APP_ENV=staging
documentation. Add a new sub-task step (such as Step 2.5 under Task 1) that
explicitly instructs to update backend/.env.example to document both
SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
docs/superpowers/specs/2026-06-21-staging-environment-design.md (1)

212-221: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Vary sentence structure in the phases list to improve readability.

Lines 216–221 have repetitive sentence beginnings ("Phase X"), which LanguageTool flagged. While this structure is functional, consider alternating phrasing to improve prose flow. For example:

  • "Phase 0 — migration runner + ordered/idempotent migrations" (current)
  • "Bring the migration runner and ordered/idempotent migrations online (Phase 0)" (alternative)

This is a low-priority style suggestion; the current form is acceptable for a checklist-style outline.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md` around lines
212 - 221, The phases list in the Build phases section (Phase 0 through Phase 7)
has repetitive sentence structure where every item begins with "**Phase X** —"
which reduces readability. To fix this, vary the phrasing of some items by
restructuring them with different sentence beginnings while preserving the phase
numbers and core content. For example, some items could reorder the phase
reference to the end in parentheses (like "Set up X (Phase Y)"), while others
could keep the original format, creating an alternating pattern that improves
prose flow without losing the checklist clarity or changing the actual
deliverables described in each phase.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@docs/superpowers/plans/2026-06-21-staging-environment.md`:
- Around line 270-276: The print statement that constructs the migration summary
message has a grammatically awkward trailing colon in the output when migrations
are handled. Modify the conditional print statement to remove the trailing colon
from the migration count message, ensuring the summary line is cleanly separated
from the list of migration names that follows on subsequent lines.
- Around line 31-38: The staging environment plan lists backend/.env.example as
a modified file in the file structure section but does not include an explicit
task step that covers updating it with the new SUPABASE_DB_URL and
APP_ENV=staging documentation. Add a new sub-task step (such as Step 2.5 under
Task 1) that explicitly instructs to update backend/.env.example to document
both SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md`:
- Around line 212-221: The phases list in the Build phases section (Phase 0
through Phase 7) has repetitive sentence structure where every item begins with
"**Phase X** —" which reduces readability. To fix this, vary the phrasing of
some items by restructuring them with different sentence beginnings while
preserving the phase numbers and core content. For example, some items could
reorder the phase reference to the end in parentheses (like "Set up X (Phase
Y)"), while others could keep the original format, creating an alternating
pattern that improves prose flow without losing the checklist clarity or
changing the actual deliverables described in each phase.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f8b34cd0-702f-473a-981d-26c4f89dfb86

📥 Commits

Reviewing files that changed from the base of the PR and between 4521305 and 06766b8.

📒 Files selected for processing (2)
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Jun 24, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7fe5c14Commit Preview URL

Branch Preview URL
Jun 24 2026, 02:34 PM

@AndresL230
AndresL230 merged commit e887251 into mainJul 8, 2026
6 checks passed
@AndresL230
AndresL230 deleted the docs/staging-environment-plan branch August 2, 2026 18:29
Sign up for freeto 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

@AndresL230@Jose-Gael-Cruz-Lopez
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

docs: staging environment design + implementation plan - #246

Merged
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan
Jul 8, 2026
Merged

docs: staging environment design + implementation plan#246
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan

Conversation

@AndresL230

@AndresL230AndresL230 commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

What

Adds the design spec and a task-by-task implementation plan for an admin-only, fully-hosted staging environment — a parallel mini-prod (Cloudflare Workers frontend + Railway backend + a dedicated Supabase project) where DB migrations and bugfixes can be verified before reaching prod.

Docs only — no code/behavior changes. This PR is the planning artifact; implementation lands in follow-up PRs per the plan's tasks (which is itself a first exercise of the trunk-based workflow the plan defines).

  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
  • docs/superpowers/plans/2026-06-21-staging-environment.md

Key decisions captured

  • Same code, different config. Staging differs from prod only by env vars — no divergent branch to reconcile.
  • Git model: trunk-based. main continuously deploys to staging; a production branch (fast-forwarded from a verified main commit) deploys to prod.
  • Migration runner (Hand-applied migrations have no runner/ordering table — drift hazard #197 — runner already merged on main via its own PR): a ~50-line psycopg-based backend/db/migrate.py over the Supabase direct connection, with a schema_migrations tracking table and ordered migrations/ dir. Also makes migration_cosmetics.sql idempotent (migration_cosmetics.sql adds FK constraints non-idempotently — re-run fails #196).
  • Test data: synthetic seed + deliberately-broken "dirty fixtures" that reproduce backlog failure modes so each fix can be proven.
  • Access control: Cloudflare Access (Zero Trust) on both staging hostnames + noindex; admin email allowlist; service token on the Worker→backend hop.

Backlog this environment de-risks

Migration plumbing (#197, #196); data-integrity migrations (#195, #181, #180, #179); index additions (#178, #177, #176, #161, #160); backend bugs (#158, #168); frontend bugs (#191, #186, #185, #184, #183, #166, #165, #164); prerequisite #163 (dep pinning, tracked separately).

Notes / open questions

  • Share prod Gemini key with staging vs. a separate key.
  • Separate Logfire project for staging vs. mixed traces.
  • Adopting the migration runner against the existing prod DB needs a one-time --baseline run (documented in the plan).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added extensive staging environment design specification and implementation plan documenting a separate, fully-hosted parallel infrastructure stack that mirrors production without sharing live state. Includes trunk-based deployment workflows, access controls, environment configuration, data seeding procedures, security measures (encryption and indexing prevention), and comprehensive operational guidance for staging platform management and pre-production validation testing.

Design spec and task-by-task plan for an admin-only, fully-hosted staging
environment (Cloudflare Workers frontend + Railway backend + dedicated Supabase
project). Includes a psycopg migration runner to close#197, idempotency fix for
#196, trunk-based deploy model, and Cloudflare Access gating. Links the
data-integrity / index / bug backlog the environment de-risks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Jose-Gael-Cruz-Lopez, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 59 minutes and 20 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7118d819-eb67-4c05-9548-7d15cc914ee1

📥 Commits

Reviewing files that changed from the base of the PR and between 06766b8 and 7fe5c14.

📒 Files selected for processing (3)
  • backend/.env.example
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
📝 Walkthrough

Walkthrough

Two new documentation files are added: a design spec (docs/superpowers/specs/2026-06-21-staging-environment-design.md) and a phased implementation plan (docs/superpowers/plans/2026-06-21-staging-environment.md). Together they define an admin-only, fully-hosted staging environment mirroring production via environment variables, a new psycopg-based migration runner, Supabase/Railway/Cloudflare Workers staging setup, and Cloudflare Access gating.

Changes

Staging Environment Documentation

Layer / File(s)Summary
Staging design spec: goals, architecture, and decisions
docs/superpowers/specs/2026-06-21-staging-environment-design.md
Defines isolation rules, v1 goals/non-goals, trunk-based deployment model, Cloudflare Access + noindex decisions, repo change inventory, full architecture (Supabase, Railway, Workers, OAuth, DNS, seed/fixtures, migration runner contract), promotion workflow, phased rollout, backlog enablement mapping, operational risks, and resolved decisions.
Implementation plan: header, constraints, and file map
docs/superpowers/plans/2026-06-21-staging-environment.md
Documents plan title, goal, architecture overview, tech stack, global constraints (DB access paths, encryption rules, secret segregation, dependency pinning), and the complete file-structure outcome map for all new and modified repo artifacts.
Phase 0: psycopg dependency, migration directory, and migrate.py runner
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 1–5: adds psycopg[binary] dependency, reorganizes SQL migrations into a numbered backend/db/migrations/ directory, specifies TDD steps for discover_migrations/pending_migrations pure functions, expands runner with DB tracking table and CLI entrypoint, and makes migration_cosmetics idempotent via DO-block FK guards.
Phase 1: staging Supabase bootstrap, secrets, seed, and dirty fixtures
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 6–8: creates and bootstraps the staging Supabase project via direct connection, generates distinct staging encryption and session secrets, runs a synthetic seed script through PostgREST using encrypt_if_present, and adds dirty_fixtures.sql to reproduce specific backlog failure modes.
Phases 2–3: Google OAuth client and Railway staging environment
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 9 covers creating the Sapling Staging Google OAuth client. Task 10 defines the full Railway staging env-var matrix including distinct Supabase URLs, staging secrets, OAuth credentials, and APP_ENV=staging, plus backend boot verification steps.
Phases 4–5: Cloudflare Workers staging deploy, DNS wiring, and smoke tests
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 11 documents wrangler staging environment configuration and the cf:deploy:staging script. Task 12 covers DNS wiring for staging.saplinglearn.com, api.staging.saplinglearn.com resolution, and the end-to-end smoke test flow including dirty-fixture behavior verification.
Phases 6–7: noindex middleware, Cloudflare Access policies, and trunk-based promotion
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 13 specifies APP_ENV=staging recognition and X-Robots-Tag: noindex, nofollow middleware. Task 14 is the Cloudflare Access operator runbook. Task 15 documents trunk-based deploy wiring, the fast-forward promotion sequence, and self-review notes on baseline caveats and schema reconciliation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • [P1] Set up a staging environment to stop testing on production #100: This PR directly implements the staging environment specification and execution plan described in issue #100, covering the same concepts: separate encryption keys, Cloudflare Access gating, environment-variable configuration, ordered SQL migrations, psycopg migration runner, and phased rollout strategy.

Poem

🐇 Hop, hop through the staging gate,
A mirror of prod — but isolated, great!
Migrations ordered, secrets kept apart,
Cloudflare guards the access with art.
noindex whispers: "search engines, away!"
The rabbit tests safely, then promotes the day. 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe pull request title clearly and concisely summarizes the main change: adding documentation for staging environment design and implementation plan.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description check✅ PassedThe description is detailed and covers purpose, decisions, impact, and open questions, with only minor template heading mismatches.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/staging-environment-plan

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitUpdated (UTC)
❌ Deployment failed
View logs
frontend06766b8Jun 22 2026, 03:56 AM

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (3)
docs/superpowers/plans/2026-06-21-staging-environment.md (2)

270-276: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Minor: Improve the CLI output message grammar.

Line 274's message construction results in "Applied 5 migration(s):" (with a trailing colon) before listing migrations, which is grammatically awkward. Consider simplifying to match typical CLI patterns:

🔧 Suggested revision
- verb = "Baselined" if baseline else "Applied"- print(f"{verb} {len(handled)} migration(s):" if handled else "No pending migrations.")- for name in handled:- print(f" - {name}")+ if handled:+ verb = "Baselined" if baseline else "Applied"+ print(f"{verb} {len(handled)} migration(s).")+ for name in handled:+ print(f" - {name}")+ else:+ print("No pending migrations.")

This separates the summary line from the list and removes the trailing colon.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 270 -
276, The print statement that constructs the migration summary message has a
grammatically awkward trailing colon in the output when migrations are handled.
Modify the conditional print statement to remove the trailing colon from the
migration count message, ensuring the summary line is cleanly separated from the
list of migration names that follows on subsequent lines.

31-38: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add explicit step to update .env.example.

The file structure lists backend/.env.example as modified (to document SUPABASE_DB_URL and APP_ENV=staging), but no task explicitly covers this update. Consider adding a step in Task 1 (psycopg dependency) or creating a standalone "documentation" sub-task to ensure this is not overlooked.

💡 Suggested addition to Task 1, Step 3 (before commit)
-[ ]**Step 2.5: Update `.env.example`** (if not already documented)
Run: `grep -q "SUPABASE_DB_URL" backend/.env.example || echo "SUPABASE_DB_URL=postgresql://..." >> backend/.env.example`
Ensure the file documents both `SUPABASE_DB_URL` (for migration runner) and `APP_ENV=staging` as examples.

Then update the existing Step 3 commit message to reference .env.example:

git add backend/requirements.txt backend/.env.example
git commit -m "build: add psycopg dependency + document SUPABASE_DB_URL in .env.example (`#197`)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 31 -
38, The staging environment plan lists backend/.env.example as a modified file
in the file structure section but does not include an explicit task step that
covers updating it with the new SUPABASE_DB_URL and APP_ENV=staging
documentation. Add a new sub-task step (such as Step 2.5 under Task 1) that
explicitly instructs to update backend/.env.example to document both
SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
docs/superpowers/specs/2026-06-21-staging-environment-design.md (1)

212-221: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Vary sentence structure in the phases list to improve readability.

Lines 216–221 have repetitive sentence beginnings ("Phase X"), which LanguageTool flagged. While this structure is functional, consider alternating phrasing to improve prose flow. For example:

  • "Phase 0 — migration runner + ordered/idempotent migrations" (current)
  • "Bring the migration runner and ordered/idempotent migrations online (Phase 0)" (alternative)

This is a low-priority style suggestion; the current form is acceptable for a checklist-style outline.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md` around lines
212 - 221, The phases list in the Build phases section (Phase 0 through Phase 7)
has repetitive sentence structure where every item begins with "**Phase X** —"
which reduces readability. To fix this, vary the phrasing of some items by
restructuring them with different sentence beginnings while preserving the phase
numbers and core content. For example, some items could reorder the phase
reference to the end in parentheses (like "Set up X (Phase Y)"), while others
could keep the original format, creating an alternating pattern that improves
prose flow without losing the checklist clarity or changing the actual
deliverables described in each phase.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@docs/superpowers/plans/2026-06-21-staging-environment.md`:
- Around line 270-276: The print statement that constructs the migration summary
message has a grammatically awkward trailing colon in the output when migrations
are handled. Modify the conditional print statement to remove the trailing colon
from the migration count message, ensuring the summary line is cleanly separated
from the list of migration names that follows on subsequent lines.
- Around line 31-38: The staging environment plan lists backend/.env.example as
a modified file in the file structure section but does not include an explicit
task step that covers updating it with the new SUPABASE_DB_URL and
APP_ENV=staging documentation. Add a new sub-task step (such as Step 2.5 under
Task 1) that explicitly instructs to update backend/.env.example to document
both SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md`:
- Around line 212-221: The phases list in the Build phases section (Phase 0
through Phase 7) has repetitive sentence structure where every item begins with
"**Phase X** —" which reduces readability. To fix this, vary the phrasing of
some items by restructuring them with different sentence beginnings while
preserving the phase numbers and core content. For example, some items could
reorder the phase reference to the end in parentheses (like "Set up X (Phase
Y)"), while others could keep the original format, creating an alternating
pattern that improves prose flow without losing the checklist clarity or
changing the actual deliverables described in each phase.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f8b34cd0-702f-473a-981d-26c4f89dfb86

📥 Commits

Reviewing files that changed from the base of the PR and between 4521305 and 06766b8.

📒 Files selected for processing (2)
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Jun 24, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7fe5c14Commit Preview URL

Branch Preview URL
Jun 24 2026, 02:34 PM

@AndresL230
AndresL230 merged commit e887251 into mainJul 8, 2026
6 checks passed
@AndresL230
AndresL230 deleted the docs/staging-environment-plan branch August 2, 2026 18:29
Sign up for freeto 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

@AndresL230@Jose-Gael-Cruz-Lopez
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs: staging environment design + implementation plan - #246

Merged
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan
Jul 8, 2026
Merged

docs: staging environment design + implementation plan#246
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan

Conversation

@AndresL230

@AndresL230AndresL230 commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

What

Adds the design spec and a task-by-task implementation plan for an admin-only, fully-hosted staging environment — a parallel mini-prod (Cloudflare Workers frontend + Railway backend + a dedicated Supabase project) where DB migrations and bugfixes can be verified before reaching prod.

Docs only — no code/behavior changes. This PR is the planning artifact; implementation lands in follow-up PRs per the plan's tasks (which is itself a first exercise of the trunk-based workflow the plan defines).

  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
  • docs/superpowers/plans/2026-06-21-staging-environment.md

Key decisions captured

  • Same code, different config. Staging differs from prod only by env vars — no divergent branch to reconcile.
  • Git model: trunk-based. main continuously deploys to staging; a production branch (fast-forwarded from a verified main commit) deploys to prod.
  • Migration runner (Hand-applied migrations have no runner/ordering table — drift hazard #197 — runner already merged on main via its own PR): a ~50-line psycopg-based backend/db/migrate.py over the Supabase direct connection, with a schema_migrations tracking table and ordered migrations/ dir. Also makes migration_cosmetics.sql idempotent (migration_cosmetics.sql adds FK constraints non-idempotently — re-run fails #196).
  • Test data: synthetic seed + deliberately-broken "dirty fixtures" that reproduce backlog failure modes so each fix can be proven.
  • Access control: Cloudflare Access (Zero Trust) on both staging hostnames + noindex; admin email allowlist; service token on the Worker→backend hop.

Backlog this environment de-risks

Migration plumbing (#197, #196); data-integrity migrations (#195, #181, #180, #179); index additions (#178, #177, #176, #161, #160); backend bugs (#158, #168); frontend bugs (#191, #186, #185, #184, #183, #166, #165, #164); prerequisite #163 (dep pinning, tracked separately).

Notes / open questions

  • Share prod Gemini key with staging vs. a separate key.
  • Separate Logfire project for staging vs. mixed traces.
  • Adopting the migration runner against the existing prod DB needs a one-time --baseline run (documented in the plan).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added extensive staging environment design specification and implementation plan documenting a separate, fully-hosted parallel infrastructure stack that mirrors production without sharing live state. Includes trunk-based deployment workflows, access controls, environment configuration, data seeding procedures, security measures (encryption and indexing prevention), and comprehensive operational guidance for staging platform management and pre-production validation testing.

Design spec and task-by-task plan for an admin-only, fully-hosted staging
environment (Cloudflare Workers frontend + Railway backend + dedicated Supabase
project). Includes a psycopg migration runner to close#197, idempotency fix for
#196, trunk-based deploy model, and Cloudflare Access gating. Links the
data-integrity / index / bug backlog the environment de-risks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Jose-Gael-Cruz-Lopez, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 59 minutes and 20 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7118d819-eb67-4c05-9548-7d15cc914ee1

📥 Commits

Reviewing files that changed from the base of the PR and between 06766b8 and 7fe5c14.

📒 Files selected for processing (3)
  • backend/.env.example
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
📝 Walkthrough

Walkthrough

Two new documentation files are added: a design spec (docs/superpowers/specs/2026-06-21-staging-environment-design.md) and a phased implementation plan (docs/superpowers/plans/2026-06-21-staging-environment.md). Together they define an admin-only, fully-hosted staging environment mirroring production via environment variables, a new psycopg-based migration runner, Supabase/Railway/Cloudflare Workers staging setup, and Cloudflare Access gating.

Changes

Staging Environment Documentation

Layer / File(s)Summary
Staging design spec: goals, architecture, and decisions
docs/superpowers/specs/2026-06-21-staging-environment-design.md
Defines isolation rules, v1 goals/non-goals, trunk-based deployment model, Cloudflare Access + noindex decisions, repo change inventory, full architecture (Supabase, Railway, Workers, OAuth, DNS, seed/fixtures, migration runner contract), promotion workflow, phased rollout, backlog enablement mapping, operational risks, and resolved decisions.
Implementation plan: header, constraints, and file map
docs/superpowers/plans/2026-06-21-staging-environment.md
Documents plan title, goal, architecture overview, tech stack, global constraints (DB access paths, encryption rules, secret segregation, dependency pinning), and the complete file-structure outcome map for all new and modified repo artifacts.
Phase 0: psycopg dependency, migration directory, and migrate.py runner
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 1–5: adds psycopg[binary] dependency, reorganizes SQL migrations into a numbered backend/db/migrations/ directory, specifies TDD steps for discover_migrations/pending_migrations pure functions, expands runner with DB tracking table and CLI entrypoint, and makes migration_cosmetics idempotent via DO-block FK guards.
Phase 1: staging Supabase bootstrap, secrets, seed, and dirty fixtures
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 6–8: creates and bootstraps the staging Supabase project via direct connection, generates distinct staging encryption and session secrets, runs a synthetic seed script through PostgREST using encrypt_if_present, and adds dirty_fixtures.sql to reproduce specific backlog failure modes.
Phases 2–3: Google OAuth client and Railway staging environment
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 9 covers creating the Sapling Staging Google OAuth client. Task 10 defines the full Railway staging env-var matrix including distinct Supabase URLs, staging secrets, OAuth credentials, and APP_ENV=staging, plus backend boot verification steps.
Phases 4–5: Cloudflare Workers staging deploy, DNS wiring, and smoke tests
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 11 documents wrangler staging environment configuration and the cf:deploy:staging script. Task 12 covers DNS wiring for staging.saplinglearn.com, api.staging.saplinglearn.com resolution, and the end-to-end smoke test flow including dirty-fixture behavior verification.
Phases 6–7: noindex middleware, Cloudflare Access policies, and trunk-based promotion
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 13 specifies APP_ENV=staging recognition and X-Robots-Tag: noindex, nofollow middleware. Task 14 is the Cloudflare Access operator runbook. Task 15 documents trunk-based deploy wiring, the fast-forward promotion sequence, and self-review notes on baseline caveats and schema reconciliation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • [P1] Set up a staging environment to stop testing on production #100: This PR directly implements the staging environment specification and execution plan described in issue #100, covering the same concepts: separate encryption keys, Cloudflare Access gating, environment-variable configuration, ordered SQL migrations, psycopg migration runner, and phased rollout strategy.

Poem

🐇 Hop, hop through the staging gate,
A mirror of prod — but isolated, great!
Migrations ordered, secrets kept apart,
Cloudflare guards the access with art.
noindex whispers: "search engines, away!"
The rabbit tests safely, then promotes the day. 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe pull request title clearly and concisely summarizes the main change: adding documentation for staging environment design and implementation plan.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description check✅ PassedThe description is detailed and covers purpose, decisions, impact, and open questions, with only minor template heading mismatches.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/staging-environment-plan

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitUpdated (UTC)
❌ Deployment failed
View logs
frontend06766b8Jun 22 2026, 03:56 AM

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (3)
docs/superpowers/plans/2026-06-21-staging-environment.md (2)

270-276: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Minor: Improve the CLI output message grammar.

Line 274's message construction results in "Applied 5 migration(s):" (with a trailing colon) before listing migrations, which is grammatically awkward. Consider simplifying to match typical CLI patterns:

🔧 Suggested revision
- verb = "Baselined" if baseline else "Applied"- print(f"{verb} {len(handled)} migration(s):" if handled else "No pending migrations.")- for name in handled:- print(f" - {name}")+ if handled:+ verb = "Baselined" if baseline else "Applied"+ print(f"{verb} {len(handled)} migration(s).")+ for name in handled:+ print(f" - {name}")+ else:+ print("No pending migrations.")

This separates the summary line from the list and removes the trailing colon.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 270 -
276, The print statement that constructs the migration summary message has a
grammatically awkward trailing colon in the output when migrations are handled.
Modify the conditional print statement to remove the trailing colon from the
migration count message, ensuring the summary line is cleanly separated from the
list of migration names that follows on subsequent lines.

31-38: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add explicit step to update .env.example.

The file structure lists backend/.env.example as modified (to document SUPABASE_DB_URL and APP_ENV=staging), but no task explicitly covers this update. Consider adding a step in Task 1 (psycopg dependency) or creating a standalone "documentation" sub-task to ensure this is not overlooked.

💡 Suggested addition to Task 1, Step 3 (before commit)
-[ ]**Step 2.5: Update `.env.example`** (if not already documented)
Run: `grep -q "SUPABASE_DB_URL" backend/.env.example || echo "SUPABASE_DB_URL=postgresql://..." >> backend/.env.example`
Ensure the file documents both `SUPABASE_DB_URL` (for migration runner) and `APP_ENV=staging` as examples.

Then update the existing Step 3 commit message to reference .env.example:

git add backend/requirements.txt backend/.env.example
git commit -m "build: add psycopg dependency + document SUPABASE_DB_URL in .env.example (`#197`)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 31 -
38, The staging environment plan lists backend/.env.example as a modified file
in the file structure section but does not include an explicit task step that
covers updating it with the new SUPABASE_DB_URL and APP_ENV=staging
documentation. Add a new sub-task step (such as Step 2.5 under Task 1) that
explicitly instructs to update backend/.env.example to document both
SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
docs/superpowers/specs/2026-06-21-staging-environment-design.md (1)

212-221: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Vary sentence structure in the phases list to improve readability.

Lines 216–221 have repetitive sentence beginnings ("Phase X"), which LanguageTool flagged. While this structure is functional, consider alternating phrasing to improve prose flow. For example:

  • "Phase 0 — migration runner + ordered/idempotent migrations" (current)
  • "Bring the migration runner and ordered/idempotent migrations online (Phase 0)" (alternative)

This is a low-priority style suggestion; the current form is acceptable for a checklist-style outline.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md` around lines
212 - 221, The phases list in the Build phases section (Phase 0 through Phase 7)
has repetitive sentence structure where every item begins with "**Phase X** —"
which reduces readability. To fix this, vary the phrasing of some items by
restructuring them with different sentence beginnings while preserving the phase
numbers and core content. For example, some items could reorder the phase
reference to the end in parentheses (like "Set up X (Phase Y)"), while others
could keep the original format, creating an alternating pattern that improves
prose flow without losing the checklist clarity or changing the actual
deliverables described in each phase.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@docs/superpowers/plans/2026-06-21-staging-environment.md`:
- Around line 270-276: The print statement that constructs the migration summary
message has a grammatically awkward trailing colon in the output when migrations
are handled. Modify the conditional print statement to remove the trailing colon
from the migration count message, ensuring the summary line is cleanly separated
from the list of migration names that follows on subsequent lines.
- Around line 31-38: The staging environment plan lists backend/.env.example as
a modified file in the file structure section but does not include an explicit
task step that covers updating it with the new SUPABASE_DB_URL and
APP_ENV=staging documentation. Add a new sub-task step (such as Step 2.5 under
Task 1) that explicitly instructs to update backend/.env.example to document
both SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md`:
- Around line 212-221: The phases list in the Build phases section (Phase 0
through Phase 7) has repetitive sentence structure where every item begins with
"**Phase X** —" which reduces readability. To fix this, vary the phrasing of
some items by restructuring them with different sentence beginnings while
preserving the phase numbers and core content. For example, some items could
reorder the phase reference to the end in parentheses (like "Set up X (Phase
Y)"), while others could keep the original format, creating an alternating
pattern that improves prose flow without losing the checklist clarity or
changing the actual deliverables described in each phase.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f8b34cd0-702f-473a-981d-26c4f89dfb86

📥 Commits

Reviewing files that changed from the base of the PR and between 4521305 and 06766b8.

📒 Files selected for processing (2)
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Jun 24, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7fe5c14Commit Preview URL

Branch Preview URL
Jun 24 2026, 02:34 PM

@AndresL230
AndresL230 merged commit e887251 into mainJul 8, 2026
6 checks passed
@AndresL230
AndresL230 deleted the docs/staging-environment-plan branch August 2, 2026 18:29
Sign up for freeto 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

@AndresL230@Jose-Gael-Cruz-Lopez
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs: staging environment design + implementation plan - #246

Merged
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan
Jul 8, 2026
Merged

docs: staging environment design + implementation plan#246
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan

Conversation

@AndresL230

@AndresL230AndresL230 commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

What

Adds the design spec and a task-by-task implementation plan for an admin-only, fully-hosted staging environment — a parallel mini-prod (Cloudflare Workers frontend + Railway backend + a dedicated Supabase project) where DB migrations and bugfixes can be verified before reaching prod.

Docs only — no code/behavior changes. This PR is the planning artifact; implementation lands in follow-up PRs per the plan's tasks (which is itself a first exercise of the trunk-based workflow the plan defines).

  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
  • docs/superpowers/plans/2026-06-21-staging-environment.md

Key decisions captured

  • Same code, different config. Staging differs from prod only by env vars — no divergent branch to reconcile.
  • Git model: trunk-based. main continuously deploys to staging; a production branch (fast-forwarded from a verified main commit) deploys to prod.
  • Migration runner (Hand-applied migrations have no runner/ordering table — drift hazard #197 — runner already merged on main via its own PR): a ~50-line psycopg-based backend/db/migrate.py over the Supabase direct connection, with a schema_migrations tracking table and ordered migrations/ dir. Also makes migration_cosmetics.sql idempotent (migration_cosmetics.sql adds FK constraints non-idempotently — re-run fails #196).
  • Test data: synthetic seed + deliberately-broken "dirty fixtures" that reproduce backlog failure modes so each fix can be proven.
  • Access control: Cloudflare Access (Zero Trust) on both staging hostnames + noindex; admin email allowlist; service token on the Worker→backend hop.

Backlog this environment de-risks

Migration plumbing (#197, #196); data-integrity migrations (#195, #181, #180, #179); index additions (#178, #177, #176, #161, #160); backend bugs (#158, #168); frontend bugs (#191, #186, #185, #184, #183, #166, #165, #164); prerequisite #163 (dep pinning, tracked separately).

Notes / open questions

  • Share prod Gemini key with staging vs. a separate key.
  • Separate Logfire project for staging vs. mixed traces.
  • Adopting the migration runner against the existing prod DB needs a one-time --baseline run (documented in the plan).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added extensive staging environment design specification and implementation plan documenting a separate, fully-hosted parallel infrastructure stack that mirrors production without sharing live state. Includes trunk-based deployment workflows, access controls, environment configuration, data seeding procedures, security measures (encryption and indexing prevention), and comprehensive operational guidance for staging platform management and pre-production validation testing.

Design spec and task-by-task plan for an admin-only, fully-hosted staging
environment (Cloudflare Workers frontend + Railway backend + dedicated Supabase
project). Includes a psycopg migration runner to close#197, idempotency fix for
#196, trunk-based deploy model, and Cloudflare Access gating. Links the
data-integrity / index / bug backlog the environment de-risks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Jose-Gael-Cruz-Lopez, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 59 minutes and 20 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7118d819-eb67-4c05-9548-7d15cc914ee1

📥 Commits

Reviewing files that changed from the base of the PR and between 06766b8 and 7fe5c14.

📒 Files selected for processing (3)
  • backend/.env.example
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
📝 Walkthrough

Walkthrough

Two new documentation files are added: a design spec (docs/superpowers/specs/2026-06-21-staging-environment-design.md) and a phased implementation plan (docs/superpowers/plans/2026-06-21-staging-environment.md). Together they define an admin-only, fully-hosted staging environment mirroring production via environment variables, a new psycopg-based migration runner, Supabase/Railway/Cloudflare Workers staging setup, and Cloudflare Access gating.

Changes

Staging Environment Documentation

Layer / File(s)Summary
Staging design spec: goals, architecture, and decisions
docs/superpowers/specs/2026-06-21-staging-environment-design.md
Defines isolation rules, v1 goals/non-goals, trunk-based deployment model, Cloudflare Access + noindex decisions, repo change inventory, full architecture (Supabase, Railway, Workers, OAuth, DNS, seed/fixtures, migration runner contract), promotion workflow, phased rollout, backlog enablement mapping, operational risks, and resolved decisions.
Implementation plan: header, constraints, and file map
docs/superpowers/plans/2026-06-21-staging-environment.md
Documents plan title, goal, architecture overview, tech stack, global constraints (DB access paths, encryption rules, secret segregation, dependency pinning), and the complete file-structure outcome map for all new and modified repo artifacts.
Phase 0: psycopg dependency, migration directory, and migrate.py runner
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 1–5: adds psycopg[binary] dependency, reorganizes SQL migrations into a numbered backend/db/migrations/ directory, specifies TDD steps for discover_migrations/pending_migrations pure functions, expands runner with DB tracking table and CLI entrypoint, and makes migration_cosmetics idempotent via DO-block FK guards.
Phase 1: staging Supabase bootstrap, secrets, seed, and dirty fixtures
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 6–8: creates and bootstraps the staging Supabase project via direct connection, generates distinct staging encryption and session secrets, runs a synthetic seed script through PostgREST using encrypt_if_present, and adds dirty_fixtures.sql to reproduce specific backlog failure modes.
Phases 2–3: Google OAuth client and Railway staging environment
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 9 covers creating the Sapling Staging Google OAuth client. Task 10 defines the full Railway staging env-var matrix including distinct Supabase URLs, staging secrets, OAuth credentials, and APP_ENV=staging, plus backend boot verification steps.
Phases 4–5: Cloudflare Workers staging deploy, DNS wiring, and smoke tests
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 11 documents wrangler staging environment configuration and the cf:deploy:staging script. Task 12 covers DNS wiring for staging.saplinglearn.com, api.staging.saplinglearn.com resolution, and the end-to-end smoke test flow including dirty-fixture behavior verification.
Phases 6–7: noindex middleware, Cloudflare Access policies, and trunk-based promotion
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 13 specifies APP_ENV=staging recognition and X-Robots-Tag: noindex, nofollow middleware. Task 14 is the Cloudflare Access operator runbook. Task 15 documents trunk-based deploy wiring, the fast-forward promotion sequence, and self-review notes on baseline caveats and schema reconciliation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • [P1] Set up a staging environment to stop testing on production #100: This PR directly implements the staging environment specification and execution plan described in issue #100, covering the same concepts: separate encryption keys, Cloudflare Access gating, environment-variable configuration, ordered SQL migrations, psycopg migration runner, and phased rollout strategy.

Poem

🐇 Hop, hop through the staging gate,
A mirror of prod — but isolated, great!
Migrations ordered, secrets kept apart,
Cloudflare guards the access with art.
noindex whispers: "search engines, away!"
The rabbit tests safely, then promotes the day. 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe pull request title clearly and concisely summarizes the main change: adding documentation for staging environment design and implementation plan.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description check✅ PassedThe description is detailed and covers purpose, decisions, impact, and open questions, with only minor template heading mismatches.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/staging-environment-plan

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitUpdated (UTC)
❌ Deployment failed
View logs
frontend06766b8Jun 22 2026, 03:56 AM

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (3)
docs/superpowers/plans/2026-06-21-staging-environment.md (2)

270-276: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Minor: Improve the CLI output message grammar.

Line 274's message construction results in "Applied 5 migration(s):" (with a trailing colon) before listing migrations, which is grammatically awkward. Consider simplifying to match typical CLI patterns:

🔧 Suggested revision
- verb = "Baselined" if baseline else "Applied"- print(f"{verb} {len(handled)} migration(s):" if handled else "No pending migrations.")- for name in handled:- print(f" - {name}")+ if handled:+ verb = "Baselined" if baseline else "Applied"+ print(f"{verb} {len(handled)} migration(s).")+ for name in handled:+ print(f" - {name}")+ else:+ print("No pending migrations.")

This separates the summary line from the list and removes the trailing colon.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 270 -
276, The print statement that constructs the migration summary message has a
grammatically awkward trailing colon in the output when migrations are handled.
Modify the conditional print statement to remove the trailing colon from the
migration count message, ensuring the summary line is cleanly separated from the
list of migration names that follows on subsequent lines.

31-38: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add explicit step to update .env.example.

The file structure lists backend/.env.example as modified (to document SUPABASE_DB_URL and APP_ENV=staging), but no task explicitly covers this update. Consider adding a step in Task 1 (psycopg dependency) or creating a standalone "documentation" sub-task to ensure this is not overlooked.

💡 Suggested addition to Task 1, Step 3 (before commit)
-[ ]**Step 2.5: Update `.env.example`** (if not already documented)
Run: `grep -q "SUPABASE_DB_URL" backend/.env.example || echo "SUPABASE_DB_URL=postgresql://..." >> backend/.env.example`
Ensure the file documents both `SUPABASE_DB_URL` (for migration runner) and `APP_ENV=staging` as examples.

Then update the existing Step 3 commit message to reference .env.example:

git add backend/requirements.txt backend/.env.example
git commit -m "build: add psycopg dependency + document SUPABASE_DB_URL in .env.example (`#197`)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 31 -
38, The staging environment plan lists backend/.env.example as a modified file
in the file structure section but does not include an explicit task step that
covers updating it with the new SUPABASE_DB_URL and APP_ENV=staging
documentation. Add a new sub-task step (such as Step 2.5 under Task 1) that
explicitly instructs to update backend/.env.example to document both
SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
docs/superpowers/specs/2026-06-21-staging-environment-design.md (1)

212-221: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Vary sentence structure in the phases list to improve readability.

Lines 216–221 have repetitive sentence beginnings ("Phase X"), which LanguageTool flagged. While this structure is functional, consider alternating phrasing to improve prose flow. For example:

  • "Phase 0 — migration runner + ordered/idempotent migrations" (current)
  • "Bring the migration runner and ordered/idempotent migrations online (Phase 0)" (alternative)

This is a low-priority style suggestion; the current form is acceptable for a checklist-style outline.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md` around lines
212 - 221, The phases list in the Build phases section (Phase 0 through Phase 7)
has repetitive sentence structure where every item begins with "**Phase X** —"
which reduces readability. To fix this, vary the phrasing of some items by
restructuring them with different sentence beginnings while preserving the phase
numbers and core content. For example, some items could reorder the phase
reference to the end in parentheses (like "Set up X (Phase Y)"), while others
could keep the original format, creating an alternating pattern that improves
prose flow without losing the checklist clarity or changing the actual
deliverables described in each phase.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@docs/superpowers/plans/2026-06-21-staging-environment.md`:
- Around line 270-276: The print statement that constructs the migration summary
message has a grammatically awkward trailing colon in the output when migrations
are handled. Modify the conditional print statement to remove the trailing colon
from the migration count message, ensuring the summary line is cleanly separated
from the list of migration names that follows on subsequent lines.
- Around line 31-38: The staging environment plan lists backend/.env.example as
a modified file in the file structure section but does not include an explicit
task step that covers updating it with the new SUPABASE_DB_URL and
APP_ENV=staging documentation. Add a new sub-task step (such as Step 2.5 under
Task 1) that explicitly instructs to update backend/.env.example to document
both SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md`:
- Around line 212-221: The phases list in the Build phases section (Phase 0
through Phase 7) has repetitive sentence structure where every item begins with
"**Phase X** —" which reduces readability. To fix this, vary the phrasing of
some items by restructuring them with different sentence beginnings while
preserving the phase numbers and core content. For example, some items could
reorder the phase reference to the end in parentheses (like "Set up X (Phase
Y)"), while others could keep the original format, creating an alternating
pattern that improves prose flow without losing the checklist clarity or
changing the actual deliverables described in each phase.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f8b34cd0-702f-473a-981d-26c4f89dfb86

📥 Commits

Reviewing files that changed from the base of the PR and between 4521305 and 06766b8.

📒 Files selected for processing (2)
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Jun 24, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7fe5c14Commit Preview URL

Branch Preview URL
Jun 24 2026, 02:34 PM

@AndresL230
AndresL230 merged commit e887251 into mainJul 8, 2026
6 checks passed
@AndresL230
AndresL230 deleted the docs/staging-environment-plan branch August 2, 2026 18:29
Sign up for freeto 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

@AndresL230@Jose-Gael-Cruz-Lopez
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

docs: staging environment design + implementation plan - #246

Merged
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan
Jul 8, 2026
Merged

docs: staging environment design + implementation plan#246
AndresL230 merged 8 commits into
mainfrom
docs/staging-environment-plan

Conversation

@AndresL230

@AndresL230AndresL230 commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

What

Adds the design spec and a task-by-task implementation plan for an admin-only, fully-hosted staging environment — a parallel mini-prod (Cloudflare Workers frontend + Railway backend + a dedicated Supabase project) where DB migrations and bugfixes can be verified before reaching prod.

Docs only — no code/behavior changes. This PR is the planning artifact; implementation lands in follow-up PRs per the plan's tasks (which is itself a first exercise of the trunk-based workflow the plan defines).

  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
  • docs/superpowers/plans/2026-06-21-staging-environment.md

Key decisions captured

  • Same code, different config. Staging differs from prod only by env vars — no divergent branch to reconcile.
  • Git model: trunk-based. main continuously deploys to staging; a production branch (fast-forwarded from a verified main commit) deploys to prod.
  • Migration runner (Hand-applied migrations have no runner/ordering table — drift hazard #197 — runner already merged on main via its own PR): a ~50-line psycopg-based backend/db/migrate.py over the Supabase direct connection, with a schema_migrations tracking table and ordered migrations/ dir. Also makes migration_cosmetics.sql idempotent (migration_cosmetics.sql adds FK constraints non-idempotently — re-run fails #196).
  • Test data: synthetic seed + deliberately-broken "dirty fixtures" that reproduce backlog failure modes so each fix can be proven.
  • Access control: Cloudflare Access (Zero Trust) on both staging hostnames + noindex; admin email allowlist; service token on the Worker→backend hop.

Backlog this environment de-risks

Migration plumbing (#197, #196); data-integrity migrations (#195, #181, #180, #179); index additions (#178, #177, #176, #161, #160); backend bugs (#158, #168); frontend bugs (#191, #186, #185, #184, #183, #166, #165, #164); prerequisite #163 (dep pinning, tracked separately).

Notes / open questions

  • Share prod Gemini key with staging vs. a separate key.
  • Separate Logfire project for staging vs. mixed traces.
  • Adopting the migration runner against the existing prod DB needs a one-time --baseline run (documented in the plan).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added extensive staging environment design specification and implementation plan documenting a separate, fully-hosted parallel infrastructure stack that mirrors production without sharing live state. Includes trunk-based deployment workflows, access controls, environment configuration, data seeding procedures, security measures (encryption and indexing prevention), and comprehensive operational guidance for staging platform management and pre-production validation testing.

Design spec and task-by-task plan for an admin-only, fully-hosted staging
environment (Cloudflare Workers frontend + Railway backend + dedicated Supabase
project). Includes a psycopg migration runner to close#197, idempotency fix for
#196, trunk-based deploy model, and Cloudflare Access gating. Links the
data-integrity / index / bug backlog the environment de-risks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Jose-Gael-Cruz-Lopez, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 59 minutes and 20 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7118d819-eb67-4c05-9548-7d15cc914ee1

📥 Commits

Reviewing files that changed from the base of the PR and between 06766b8 and 7fe5c14.

📒 Files selected for processing (3)
  • backend/.env.example
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md
📝 Walkthrough

Walkthrough

Two new documentation files are added: a design spec (docs/superpowers/specs/2026-06-21-staging-environment-design.md) and a phased implementation plan (docs/superpowers/plans/2026-06-21-staging-environment.md). Together they define an admin-only, fully-hosted staging environment mirroring production via environment variables, a new psycopg-based migration runner, Supabase/Railway/Cloudflare Workers staging setup, and Cloudflare Access gating.

Changes

Staging Environment Documentation

Layer / File(s)Summary
Staging design spec: goals, architecture, and decisions
docs/superpowers/specs/2026-06-21-staging-environment-design.md
Defines isolation rules, v1 goals/non-goals, trunk-based deployment model, Cloudflare Access + noindex decisions, repo change inventory, full architecture (Supabase, Railway, Workers, OAuth, DNS, seed/fixtures, migration runner contract), promotion workflow, phased rollout, backlog enablement mapping, operational risks, and resolved decisions.
Implementation plan: header, constraints, and file map
docs/superpowers/plans/2026-06-21-staging-environment.md
Documents plan title, goal, architecture overview, tech stack, global constraints (DB access paths, encryption rules, secret segregation, dependency pinning), and the complete file-structure outcome map for all new and modified repo artifacts.
Phase 0: psycopg dependency, migration directory, and migrate.py runner
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 1–5: adds psycopg[binary] dependency, reorganizes SQL migrations into a numbered backend/db/migrations/ directory, specifies TDD steps for discover_migrations/pending_migrations pure functions, expands runner with DB tracking table and CLI entrypoint, and makes migration_cosmetics idempotent via DO-block FK guards.
Phase 1: staging Supabase bootstrap, secrets, seed, and dirty fixtures
docs/superpowers/plans/2026-06-21-staging-environment.md
Tasks 6–8: creates and bootstraps the staging Supabase project via direct connection, generates distinct staging encryption and session secrets, runs a synthetic seed script through PostgREST using encrypt_if_present, and adds dirty_fixtures.sql to reproduce specific backlog failure modes.
Phases 2–3: Google OAuth client and Railway staging environment
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 9 covers creating the Sapling Staging Google OAuth client. Task 10 defines the full Railway staging env-var matrix including distinct Supabase URLs, staging secrets, OAuth credentials, and APP_ENV=staging, plus backend boot verification steps.
Phases 4–5: Cloudflare Workers staging deploy, DNS wiring, and smoke tests
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 11 documents wrangler staging environment configuration and the cf:deploy:staging script. Task 12 covers DNS wiring for staging.saplinglearn.com, api.staging.saplinglearn.com resolution, and the end-to-end smoke test flow including dirty-fixture behavior verification.
Phases 6–7: noindex middleware, Cloudflare Access policies, and trunk-based promotion
docs/superpowers/plans/2026-06-21-staging-environment.md
Task 13 specifies APP_ENV=staging recognition and X-Robots-Tag: noindex, nofollow middleware. Task 14 is the Cloudflare Access operator runbook. Task 15 documents trunk-based deploy wiring, the fast-forward promotion sequence, and self-review notes on baseline caveats and schema reconciliation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • [P1] Set up a staging environment to stop testing on production #100: This PR directly implements the staging environment specification and execution plan described in issue #100, covering the same concepts: separate encryption keys, Cloudflare Access gating, environment-variable configuration, ordered SQL migrations, psycopg migration runner, and phased rollout strategy.

Poem

🐇 Hop, hop through the staging gate,
A mirror of prod — but isolated, great!
Migrations ordered, secrets kept apart,
Cloudflare guards the access with art.
noindex whispers: "search engines, away!"
The rabbit tests safely, then promotes the day. 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe pull request title clearly and concisely summarizes the main change: adding documentation for staging environment design and implementation plan.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description check✅ PassedThe description is detailed and covers purpose, decisions, impact, and open questions, with only minor template heading mismatches.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/staging-environment-plan

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitUpdated (UTC)
❌ Deployment failed
View logs
frontend06766b8Jun 22 2026, 03:56 AM

@coderabbitaicoderabbitaiBot 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.

🧹 Nitpick comments (3)
docs/superpowers/plans/2026-06-21-staging-environment.md (2)

270-276: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Minor: Improve the CLI output message grammar.

Line 274's message construction results in "Applied 5 migration(s):" (with a trailing colon) before listing migrations, which is grammatically awkward. Consider simplifying to match typical CLI patterns:

🔧 Suggested revision
- verb = "Baselined" if baseline else "Applied"- print(f"{verb} {len(handled)} migration(s):" if handled else "No pending migrations.")- for name in handled:- print(f" - {name}")+ if handled:+ verb = "Baselined" if baseline else "Applied"+ print(f"{verb} {len(handled)} migration(s).")+ for name in handled:+ print(f" - {name}")+ else:+ print("No pending migrations.")

This separates the summary line from the list and removes the trailing colon.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 270 -
276, The print statement that constructs the migration summary message has a
grammatically awkward trailing colon in the output when migrations are handled.
Modify the conditional print statement to remove the trailing colon from the
migration count message, ensuring the summary line is cleanly separated from the
list of migration names that follows on subsequent lines.

31-38: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add explicit step to update .env.example.

The file structure lists backend/.env.example as modified (to document SUPABASE_DB_URL and APP_ENV=staging), but no task explicitly covers this update. Consider adding a step in Task 1 (psycopg dependency) or creating a standalone "documentation" sub-task to ensure this is not overlooked.

💡 Suggested addition to Task 1, Step 3 (before commit)
-[ ]**Step 2.5: Update `.env.example`** (if not already documented)
Run: `grep -q "SUPABASE_DB_URL" backend/.env.example || echo "SUPABASE_DB_URL=postgresql://..." >> backend/.env.example`
Ensure the file documents both `SUPABASE_DB_URL` (for migration runner) and `APP_ENV=staging` as examples.

Then update the existing Step 3 commit message to reference .env.example:

git add backend/requirements.txt backend/.env.example
git commit -m "build: add psycopg dependency + document SUPABASE_DB_URL in .env.example (`#197`)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/plans/2026-06-21-staging-environment.md` around lines 31 -
38, The staging environment plan lists backend/.env.example as a modified file
in the file structure section but does not include an explicit task step that
covers updating it with the new SUPABASE_DB_URL and APP_ENV=staging
documentation. Add a new sub-task step (such as Step 2.5 under Task 1) that
explicitly instructs to update backend/.env.example to document both
SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
docs/superpowers/specs/2026-06-21-staging-environment-design.md (1)

212-221: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Vary sentence structure in the phases list to improve readability.

Lines 216–221 have repetitive sentence beginnings ("Phase X"), which LanguageTool flagged. While this structure is functional, consider alternating phrasing to improve prose flow. For example:

  • "Phase 0 — migration runner + ordered/idempotent migrations" (current)
  • "Bring the migration runner and ordered/idempotent migrations online (Phase 0)" (alternative)

This is a low-priority style suggestion; the current form is acceptable for a checklist-style outline.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md` around lines
212 - 221, The phases list in the Build phases section (Phase 0 through Phase 7)
has repetitive sentence structure where every item begins with "**Phase X** —"
which reduces readability. To fix this, vary the phrasing of some items by
restructuring them with different sentence beginnings while preserving the phase
numbers and core content. For example, some items could reorder the phase
reference to the end in parentheses (like "Set up X (Phase Y)"), while others
could keep the original format, creating an alternating pattern that improves
prose flow without losing the checklist clarity or changing the actual
deliverables described in each phase.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@docs/superpowers/plans/2026-06-21-staging-environment.md`:
- Around line 270-276: The print statement that constructs the migration summary
message has a grammatically awkward trailing colon in the output when migrations
are handled. Modify the conditional print statement to remove the trailing colon
from the migration count message, ensuring the summary line is cleanly separated
from the list of migration names that follows on subsequent lines.
- Around line 31-38: The staging environment plan lists backend/.env.example as
a modified file in the file structure section but does not include an explicit
task step that covers updating it with the new SUPABASE_DB_URL and
APP_ENV=staging documentation. Add a new sub-task step (such as Step 2.5 under
Task 1) that explicitly instructs to update backend/.env.example to document
both SUPABASE_DB_URL (for the migration runner) and APP_ENV=staging (for the
application environment), and update the commit message in the subsequent step
to include this file in the git add and commit commands.
In `@docs/superpowers/specs/2026-06-21-staging-environment-design.md`:
- Around line 212-221: The phases list in the Build phases section (Phase 0
through Phase 7) has repetitive sentence structure where every item begins with
"**Phase X** —" which reduces readability. To fix this, vary the phrasing of
some items by restructuring them with different sentence beginnings while
preserving the phase numbers and core content. For example, some items could
reorder the phase reference to the end in parentheses (like "Set up X (Phase
Y)"), while others could keep the original format, creating an alternating
pattern that improves prose flow without losing the checklist clarity or
changing the actual deliverables described in each phase.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f8b34cd0-702f-473a-981d-26c4f89dfb86

📥 Commits

Reviewing files that changed from the base of the PR and between 4521305 and 06766b8.

📒 Files selected for processing (2)
  • docs/superpowers/plans/2026-06-21-staging-environment.md
  • docs/superpowers/specs/2026-06-21-staging-environment-design.md

@cloudflare-workers-and-pages

cloudflare-workers-and-pagesBot commented Jun 24, 2026

Copy link
Copy Markdown

Deploying with Cloudflare Workers Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

StatusNameLatest CommitPreview URLUpdated (UTC)
✅ Deployment successful!
View logs
frontend-staging7fe5c14Commit Preview URL

Branch Preview URL
Jun 24 2026, 02:34 PM

@AndresL230
AndresL230 merged commit e887251 into mainJul 8, 2026
6 checks passed
@AndresL230
AndresL230 deleted the docs/staging-environment-plan branch August 2, 2026 18:29
Sign up for freeto 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

@AndresL230@Jose-Gael-Cruz-Lopez