Files
AgendaPro/docs/superpowers/plans/2026-07-27-demo-email-domain.md
T

11 KiB

Demo Email Domain Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Standardize demo accounts on @agendamax.demo, make every demo login explicit in the README, and migrate local and Coolify data without deleting records.

Architecture: Keep the current simple demo authentication and replace only the two platform-owned demo email constants plus their test fixtures. Apply one targeted, idempotent SQLite UPDATE to existing local and production users; appointments, businesses, and related records remain unchanged. Deploy the source through the existing GitHub mirror and verify the live app through health and login endpoints.

Tech Stack: React/Vite, Express, TypeScript, Node 22 node:sqlite, SQLite, PowerShell/OpenSSH, Coolify v4.1.2.

Global Constraints

  • Keep the demo password exactly demo1234.
  • Replace active @agendapro.demo references with @agendamax.demo; retain the old domain only in migration documentation or historical records.
  • Do not reset or delete local or production business, appointment, client, employee, ticket, or review data.
  • Never commit .env.local.ps1 or print token values.
  • Production deployment must finish before the production data migration is run.
  • If production deployment fails, stop before changing the production SQLite database and use the documented rollback path.

Task 1: Update Demo Identity References and Access Documentation

Files:

  • Modify: README.md:66-82 — show email and password for every demo account.
  • Modify: server/index.ts:38-43 — use the new default owner email.
  • Modify: server/scripts/seed.ts:315-334 — use the new admin and owner emails for fresh databases.
  • Modify: src/pages/LoginPage.tsx:8-15 — use the new default development login.
  • Modify: admin-test.mjs, e2e-test.mjs, e2e-full.mjs, server/scripts/booking-e2e.mjs, visual-audit.mjs, and any other active file returned by rg -l 'agendapro\.demo' — keep automated login fixtures aligned.
  • Modify: active plan/report documents containing executable login examples; leave the new migration specification as the historical explanation of the old domain.

Interfaces:

  • Fresh seed continues to create users with the existing schema and password.

  • The login page continues to load /api/auth/demo-users and quick-login users; only the initial email constant changes.

  • Step 1: Record the current active references and credentials

Run:

rg -n --glob '!node_modules' --glob '!data/**' 'agendapro\.demo|demo1234' .

Expected: references are limited to the known seed, login defaults, tests, README, and historical documentation; no secret token values are printed.

  • Step 2: Update the README credentials table first

The resulting table must explicitly show:

| **Admin**| `[email protected]` | `demo1234` | Administrador |
| Dueño    | `[email protected]` | `demo1234` | Daniela Reyes |

Every employee row must also include the same password in its password column. Keep the note that the login screen offers quick access.

  • Step 3: Update fresh-seed and UI constants

Use these exact values:

// server/index.ts and server/scripts/seed.ts
ownerEmail: "[email protected]"

// server/scripts/seed.ts
VALUES (NULL, '[email protected]', 'demo1234', 'Administrador', 'admin', '#0f172a')

// src/pages/LoginPage.tsx
useState(DEMO ? "[email protected]" : "")
  • Step 4: Update all active automated fixtures

Replace only the email domain in existing login assertions and fixtures. Do not change employee domains or passwords.

  • Step 5: Verify the source tree has no stale active domain

Run:

rg -n --glob '!node_modules' --glob '!data/**' --glob '!docs/superpowers/specs/**' 'agendapro\.demo' .

Expected: no output, except explicitly retained historical migration notes if they are included by the chosen glob.

Task 2: Migrate the Local SQLite Demo Users

Files:

  • Modify: local ignored database data/agendapro.db only; no tracked database files.

Interfaces:

  • Uses the existing server/db.ts connection and users table.

  • Produces updated admin/owner email rows while preserving all row counts outside users.email.

  • Step 1: Confirm the local database and take a count snapshot

Run from the repository root:

Test-Path -LiteralPath .\data\agendapro.db
node --import tsx --input-type=module -e "import { db } from './server/db.ts'; console.log(JSON.stringify({users: db.prepare('SELECT id,email,role FROM users ORDER BY id').all(), appointments: db.prepare('SELECT COUNT(*) AS c FROM appointments').get(), clients: db.prepare('SELECT COUNT(*) AS c FROM clients').get()}));"

Expected: the local database exists or the command reports that a fresh seed is required; existing appointment/client counts are recorded before mutation.

  • Step 2: Apply the idempotent local email update

Run:

node --import tsx --input-type=module -e "import { db } from './server/db.ts'; const r = db.prepare(\"UPDATE users SET email = REPLACE(email, '@agendapro.demo', '@agendamax.demo') WHERE email LIKE '%@agendapro.demo'\").run(); console.log(JSON.stringify(r));"

Expected: only the old-domain demo user rows are changed; running the same command again reports zero additional changes.

  • Step 3: Verify local credentials and preservation

Run:

node --import tsx --input-type=module -e "import { db } from './server/db.ts'; console.log(JSON.stringify({demo: db.prepare(\"SELECT email,role,password FROM users WHERE email LIKE '%@agendamax.demo' ORDER BY role\").all(), appointments: db.prepare('SELECT COUNT(*) AS c FROM appointments').get(), clients: db.prepare('SELECT COUNT(*) AS c FROM clients').get()}));"

Expected: [email protected] and [email protected] use demo1234; appointment and client counts match the snapshot.

Task 3: Run Local Regression Checks

Files:

  • No additional files; validate Task 1 and Task 2 together.

Interfaces:

  • Existing package scripts are the regression contract: typecheck, build, unit tests, and API tests.

  • Step 1: Run typecheck and build

npm run typecheck
npm run build

Expected: both commands exit with code 0.

  • Step 2: Run unit and admin/API tests
npm run test:unit
npm run test:admin
npm run test:e2e

Expected: all existing checks pass with the new admin/owner emails. If a test requires a running dev server, start the repository's documented server first without resetting the database.

  • Step 3: Inspect the final diff
git diff --check
git status --short

Expected: only intended source, test, README, and specification/plan files are changed; .env.local.ps1 and data/agendapro.db remain ignored.

Task 4: Deploy AgendaMax Through Coolify

Files:

  • Modify: the tracked AgendaPro source files from Tasks 1-3 through a normal commit.
  • Do not modify: .env.local.ps1, local SQLite files, or Coolify credentials in Git.

Interfaces:

  • Source mirror: the existing GitHub remote used by Coolify (urieljarethbusiness-cpu/agendamax).

  • Coolify application: UUID s30f7egdlkx4wyjp59o1iunc, FQDN https://agendamax.urieljareth.org.

  • Step 1: Commit only the intended tracked changes

git add README.md server/index.ts server/scripts/seed.ts src/pages/LoginPage.tsx admin-test.mjs e2e-test.mjs e2e-full.mjs server/scripts/booking-e2e.mjs visual-audit.mjs docs/superpowers/specs/2026-07-27-demo-email-domain-design.md docs/superpowers/plans/2026-07-27-demo-email-domain.md
git diff --cached --check
git commit -m "docs: standardize AgendaMax demo access"

Add any additional active fixture files found by Task 1 explicitly; never use git add ..

  • Step 2: Push the source mirror used by Coolify
git push github main

Expected: the new commit is available in the GitHub mirror without exposing credentials in output.

  • Step 3: Trigger and monitor the Coolify deploy
. .\.env.local.ps1
$h = @{ Authorization = "Bearer $env:COOLIFY_TOKEN" }
$result = Invoke-RestMethod "$env:COOLIFY_API_URL/deploy?uuid=s30f7egdlkx4wyjp59o1iunc&force=true" -Headers $h
$deployment = $result.deployments[0].deployment_uuid
Invoke-RestMethod "$env:COOLIFY_API_URL/deployments/$deployment" -Headers $h

Poll until the status is finished; do not run the production SQL migration while it is queued, in progress, or failed.

Task 5: Migrate and Verify Production Data

Files:

  • Modify: persistent SQLite database inside the running AgendaMax Coolify app container only.
  • Do not modify: source files or unrelated production tables.

Interfaces:

  • Production app data path: /app/data/agendapro.db.

  • Proxmox access: host 192.168.0.200, LXC 102; use the existing scripts/Invoke-ProxmoxSsh.ps1/ProxmoxAgent.ps1 helpers and environment variables.

  • Step 1: Identify the running AgendaMax app container and verify the old rows

Use the existing Proxmox SSH chain to run inside LXC 102:

container=$(docker ps --format '{{.ID}} {{.Names}}' | awk '$2 ~ /agendamax|s30f7/ {print $1; exit}')
test -n "$container" || { echo 'AgendaMax container not found' >&2; exit 1; }
docker exec "$container" node -e "const {DatabaseSync}=require('node:sqlite'); const db=new DatabaseSync('/app/data/agendapro.db'); console.log(db.prepare(\"SELECT id,email,role FROM users WHERE email LIKE '%@agendapro.demo' OR email LIKE '%@agendamax.demo' ORDER BY id\").all())"

Expected: the app is running the new image and the current admin/owner rows are visible before mutation.

  • Step 2: Apply the production email update
docker exec "$container" node -e "const {DatabaseSync}=require('node:sqlite'); const db=new DatabaseSync('/app/data/agendapro.db'); const r=db.prepare(\"UPDATE users SET email=REPLACE(email, '@agendapro.demo', '@agendamax.demo') WHERE email LIKE '%@agendapro.demo'\").run(); console.log(r)"

Expected: the admin and owner rows move to @agendamax.demo; no business or appointment rows are deleted.

  • Step 3: Verify live health and credentials
Invoke-RestMethod https://agendamax.urieljareth.org/api/health
Invoke-RestMethod https://agendamax.urieljareth.org/api/auth/login -Method Post -ContentType 'application/json' -Body '{"email":"[email protected]","password":"demo1234"}'
Invoke-RestMethod https://agendamax.urieljareth.org/api/auth/login -Method Post -ContentType 'application/json' -Body '{"email":"[email protected]","password":"demo1234"}'

Expected: health returns ok: true; both logins return tokens and the correct roles.

  • Step 4: Verify the deployed page and repository state

Run the existing browser/HTTP post-deploy check if available, then:

git status --short

Expected: the deployed AgendaMax page loads, no uncaught frontend errors are reported, and only intentional local follow-up changes remain.