feat(brand): unify on Deck Hearth across in-repo strings + infra (P1 brand decision)
Resolves the launch-blocking 'TCG Vault vs Deck Hearth' inconsistency called out in AGENTS.md line 5 since project setup. Operator gate-0 decision: Deck Hearth wins. Two briefs applied serially. B1 (mechanical): 7-file display + comment sweep. B2 (infrastructure): Redis prefix rename in lib/rate-limit.js (5 prefixes, accept one-time counter reset), package.json + lockfile regen (STOP-on-churn confirmed only name lines changed), admin/alice/bob email rename in seed scripts + login pre-fill + NEW idempotent migration script scripts/migrations/2026-05-24-rename-admin-email.js. Risk 4 PRESERVE applied: test/lib/permission-middleware.test.js retains admin@tcgvault.com literal with 7-line architect-authored why comment (documents pre-fix-auth-bypass bug shape; preserves historical truth per project's gotcha-documentation convention). All 5 D-decisions ratified at gate-1 (Deck Hearth / deck-hearth / deckhearth / admin@deckhearth.com / full deckhearth Redis prefix). Local: lint 128 baseline (B1 + B2), vitest 21/21 (B1 + B2). CI all green: Playwright smoke 3/3 against rebranded preview in 1m4s, forbidden-cors-headers pass, forbidden-endpoints pass, Screenshot diff pass, Vercel deployment complete. Cross-validation lineage: 4th convoy where the same 3-test smoke spec defends auth surface through sweeping change (after PR #15 Layout default-user, PR #19 CORS, PR #20 rate-limit, now this PR #21 brand rename). OPERATOR POST-MERGE ACTION REQUIRED: run 'node scripts/migrations/2026-05-24-rename-admin-email.js' against prod Neon DB before next admin login (ordering: migration FIRST, then any subsequent setup-db invocation). Migration is ESM, idempotent, UNIQUE-collision-safe. PR #21 architect-commit 50ce9ab, B1 ac8c998, B2 1c18d21.
2026-05-25 03:28:29 -04:00
|
|
|
# 🎯 Deck Hearth Collaboration Testing Guide
|
2025-07-25 12:28:04 -04:00
|
|
|
|
|
|
|
|
## 👥 Test Accounts
|
|
|
|
|
|
fix(scripts): require TEST_USERS_PASSWORD + purge weak literals from test-user helpers (#27)
`scripts/create-test-users.js` hardcoded `bcrypt.hash('alice123', 12)`
+ `bcrypt.hash('bob123', 12)` and echoed those literals back to stdout
both per-user and in a final summary block. `TESTING_GUIDE.md`'s Test
Accounts table documented the same `admin123` / `alice123` / `bob123`
trio. These were the last two weak-credential surfaces left in the
helper-script + manual-QA-doc tree after `drop-public-setup` (commits
`ff80753` + `b63b509`) and `fix-reset-db-script` (squash `3ab9bf8`,
PR #25) closed the `setup-neon-db.js` and `reset-db.js` halves of the
umbrella `purge-weak-creds-from-helpers` queued follow-up.
The fix mirrors the post-`drop-public-setup` `setup-neon-db.js`
pattern and the post-PR-#25 `reset-db.js` pattern verbatim, with one
deliberate simplification: a single `TEST_USERS_PASSWORD` env var
covers both alice + bob rather than per-user env vars (risk R2 in the
convoy file argues this — these are fixture users for the
collaboration demo flow, not independent identities, and per-user
sprawl would double the env-var contract for zero security benefit).
`createTestUsers()` now reads `process.env.TEST_USERS_PASSWORD` at the
top of the function body and exits with code 1 BEFORE opening any DB
connection if the var is unset or whitespace-only, with the same
helpful-error wording template the other two scripts use (names the
var, points at `.env.local`, suggests `openssl rand -base64 24`,
references README's "First-time admin setup" section). All four
password-echo `console.log` lines are deleted; the new summary
documents *where* the password comes from without ever printing it.
`TESTING_GUIDE.md`'s Test Accounts table is rewritten to show password
source per user instead of the literal value; the two inline
`Password: alice123` / `Password: bob123` workflow snippets are
replaced with placeholder text. Unlike the previous two convoys, no
CJS→ESM conversion was needed — `create-test-users.js` was already
top-level ESM.
Verification (all static — script is destructive and not live-tested):
`node --check scripts/create-test-users.js` exit 0; `npm run lint` 128
problems (baseline preserved, no regression); `npm run test:run` 21/21
pass; grep `scripts/ TESTING_GUIDE.md` for
`admin123|password123|test123|alice123|bob123` → 0 hits;
`TEST_USERS_PASSWORD` referenced 10 times total (5 script + 5 doc).
Operator caveat: anyone running `node scripts/create-test-users.js`
post-merge must add `TEST_USERS_PASSWORD=<value>` to their
`.env.local` first; existing alice + bob rows in already-seeded
environments are NOT rotated by re-running this script
(`ON CONFLICT (email) DO NOTHING` preserves the old hashes). Same
caveat that applies to the `drop-public-setup` admin row.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:53:24 -04:00
|
|
|
| User | Email | Role | Password source |
|
|
|
|
|
|------|-------|------|-----------------|
|
|
|
|
|
| Admin | `admin@deckhearth.com` | Admin | `ADMIN_INITIAL_PASSWORD` env var (seeded by `npm run setup-db`) |
|
|
|
|
|
| Alice | `alice@deckhearth.com` | User | `TEST_USERS_PASSWORD` env var (seeded by `node scripts/create-test-users.js`) |
|
|
|
|
|
| Bob | `bob@deckhearth.com` | User | `TEST_USERS_PASSWORD` env var (seeded by `node scripts/create-test-users.js`) |
|
|
|
|
|
|
|
|
|
|
Both env vars must be set in `.env.local` before running the
|
|
|
|
|
corresponding seed script — each script fails loud (exit 1, no DB
|
|
|
|
|
connection opened) if its env var is unset. Generate strong values
|
|
|
|
|
with `openssl rand -base64 24`; see README.md → "First-time admin
|
|
|
|
|
setup" for the canonical env-var pattern.
|
|
|
|
|
|
|
|
|
|
Alice + Bob share a single `TEST_USERS_PASSWORD` value because this is
|
|
|
|
|
a test-fixture surface; that's intentional and documented in the
|
|
|
|
|
`purge-weak-creds-from-helpers` convoy.
|
2025-07-25 12:28:04 -04:00
|
|
|
|
|
|
|
|
## 🃏 Sample Cards Available
|
|
|
|
|
|
|
|
|
|
- **Lightning Bolt** (MTG) - $2.50
|
|
|
|
|
- **Black Lotus** (MTG) - $25,000
|
|
|
|
|
- **Pikachu** (Pokemon) - $8.50
|
|
|
|
|
- **Charizard** (Pokemon) - $350
|
|
|
|
|
- **Mickey Mouse** (Lorcana) - $45
|
|
|
|
|
- **Elsa** (Lorcana) - $15.75
|
|
|
|
|
|
|
|
|
|
## 🧪 Testing Workflow
|
|
|
|
|
|
|
|
|
|
### 1. **Login as Alice**
|
|
|
|
|
```
|
fix(scripts): require TEST_USERS_PASSWORD + purge weak literals from test-user helpers (#27)
`scripts/create-test-users.js` hardcoded `bcrypt.hash('alice123', 12)`
+ `bcrypt.hash('bob123', 12)` and echoed those literals back to stdout
both per-user and in a final summary block. `TESTING_GUIDE.md`'s Test
Accounts table documented the same `admin123` / `alice123` / `bob123`
trio. These were the last two weak-credential surfaces left in the
helper-script + manual-QA-doc tree after `drop-public-setup` (commits
`ff80753` + `b63b509`) and `fix-reset-db-script` (squash `3ab9bf8`,
PR #25) closed the `setup-neon-db.js` and `reset-db.js` halves of the
umbrella `purge-weak-creds-from-helpers` queued follow-up.
The fix mirrors the post-`drop-public-setup` `setup-neon-db.js`
pattern and the post-PR-#25 `reset-db.js` pattern verbatim, with one
deliberate simplification: a single `TEST_USERS_PASSWORD` env var
covers both alice + bob rather than per-user env vars (risk R2 in the
convoy file argues this — these are fixture users for the
collaboration demo flow, not independent identities, and per-user
sprawl would double the env-var contract for zero security benefit).
`createTestUsers()` now reads `process.env.TEST_USERS_PASSWORD` at the
top of the function body and exits with code 1 BEFORE opening any DB
connection if the var is unset or whitespace-only, with the same
helpful-error wording template the other two scripts use (names the
var, points at `.env.local`, suggests `openssl rand -base64 24`,
references README's "First-time admin setup" section). All four
password-echo `console.log` lines are deleted; the new summary
documents *where* the password comes from without ever printing it.
`TESTING_GUIDE.md`'s Test Accounts table is rewritten to show password
source per user instead of the literal value; the two inline
`Password: alice123` / `Password: bob123` workflow snippets are
replaced with placeholder text. Unlike the previous two convoys, no
CJS→ESM conversion was needed — `create-test-users.js` was already
top-level ESM.
Verification (all static — script is destructive and not live-tested):
`node --check scripts/create-test-users.js` exit 0; `npm run lint` 128
problems (baseline preserved, no regression); `npm run test:run` 21/21
pass; grep `scripts/ TESTING_GUIDE.md` for
`admin123|password123|test123|alice123|bob123` → 0 hits;
`TEST_USERS_PASSWORD` referenced 10 times total (5 script + 5 doc).
Operator caveat: anyone running `node scripts/create-test-users.js`
post-merge must add `TEST_USERS_PASSWORD=<value>` to their
`.env.local` first; existing alice + bob rows in already-seeded
environments are NOT rotated by re-running this script
(`ON CONFLICT (email) DO NOTHING` preserves the old hashes). Same
caveat that applies to the `drop-public-setup` admin row.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:53:24 -04:00
|
|
|
Email: alice@deckhearth.com
|
|
|
|
|
Password: <value of TEST_USERS_PASSWORD from .env.local>
|
2025-07-25 12:28:04 -04:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 2. **Create a Collection**
|
|
|
|
|
- Go to `/collections`
|
|
|
|
|
- Click "Create Collection"
|
|
|
|
|
- Fill out:
|
|
|
|
|
- Name: "Alice's Pokemon Collection"
|
|
|
|
|
- Description: "My favorite Pokemon cards"
|
|
|
|
|
- Image: (optional) `https://images.unsplash.com/photo-1606092195730-5d7b9af1efc5?w=1200`
|
|
|
|
|
- Show in Community: Toggle ON for public visibility
|
|
|
|
|
|
|
|
|
|
### 3. **Add Cards to Collection**
|
|
|
|
|
- Navigate to the new collection (auto-redirect after creation)
|
|
|
|
|
- Use "Quick Add" search in empty state
|
|
|
|
|
- Search for "Pikachu" and click to add
|
|
|
|
|
- Search for "Charizard" and click to add
|
|
|
|
|
- See real-time collection value updates
|
|
|
|
|
|
|
|
|
|
### 4. **Invite Bob as Collaborator**
|
|
|
|
|
- Click "Invite Collaborator" button
|
feat(brand): unify on Deck Hearth across in-repo strings + infra (P1 brand decision)
Resolves the launch-blocking 'TCG Vault vs Deck Hearth' inconsistency called out in AGENTS.md line 5 since project setup. Operator gate-0 decision: Deck Hearth wins. Two briefs applied serially. B1 (mechanical): 7-file display + comment sweep. B2 (infrastructure): Redis prefix rename in lib/rate-limit.js (5 prefixes, accept one-time counter reset), package.json + lockfile regen (STOP-on-churn confirmed only name lines changed), admin/alice/bob email rename in seed scripts + login pre-fill + NEW idempotent migration script scripts/migrations/2026-05-24-rename-admin-email.js. Risk 4 PRESERVE applied: test/lib/permission-middleware.test.js retains admin@tcgvault.com literal with 7-line architect-authored why comment (documents pre-fix-auth-bypass bug shape; preserves historical truth per project's gotcha-documentation convention). All 5 D-decisions ratified at gate-1 (Deck Hearth / deck-hearth / deckhearth / admin@deckhearth.com / full deckhearth Redis prefix). Local: lint 128 baseline (B1 + B2), vitest 21/21 (B1 + B2). CI all green: Playwright smoke 3/3 against rebranded preview in 1m4s, forbidden-cors-headers pass, forbidden-endpoints pass, Screenshot diff pass, Vercel deployment complete. Cross-validation lineage: 4th convoy where the same 3-test smoke spec defends auth surface through sweeping change (after PR #15 Layout default-user, PR #19 CORS, PR #20 rate-limit, now this PR #21 brand rename). OPERATOR POST-MERGE ACTION REQUIRED: run 'node scripts/migrations/2026-05-24-rename-admin-email.js' against prod Neon DB before next admin login (ordering: migration FIRST, then any subsequent setup-db invocation). Migration is ESM, idempotent, UNIQUE-collision-safe. PR #21 architect-commit 50ce9ab, B1 ac8c998, B2 1c18d21.
2026-05-25 03:28:29 -04:00
|
|
|
- Enter: `bob@deckhearth.com`
|
2025-07-25 12:28:04 -04:00
|
|
|
- Role: Collaborator (default)
|
|
|
|
|
- Message: "Help me build this Pokemon collection!"
|
|
|
|
|
- Click "Send Invitation"
|
|
|
|
|
|
|
|
|
|
### 5. **Switch to Bob's Account**
|
|
|
|
|
- Logout and login as Bob
|
feat(brand): unify on Deck Hearth across in-repo strings + infra (P1 brand decision)
Resolves the launch-blocking 'TCG Vault vs Deck Hearth' inconsistency called out in AGENTS.md line 5 since project setup. Operator gate-0 decision: Deck Hearth wins. Two briefs applied serially. B1 (mechanical): 7-file display + comment sweep. B2 (infrastructure): Redis prefix rename in lib/rate-limit.js (5 prefixes, accept one-time counter reset), package.json + lockfile regen (STOP-on-churn confirmed only name lines changed), admin/alice/bob email rename in seed scripts + login pre-fill + NEW idempotent migration script scripts/migrations/2026-05-24-rename-admin-email.js. Risk 4 PRESERVE applied: test/lib/permission-middleware.test.js retains admin@tcgvault.com literal with 7-line architect-authored why comment (documents pre-fix-auth-bypass bug shape; preserves historical truth per project's gotcha-documentation convention). All 5 D-decisions ratified at gate-1 (Deck Hearth / deck-hearth / deckhearth / admin@deckhearth.com / full deckhearth Redis prefix). Local: lint 128 baseline (B1 + B2), vitest 21/21 (B1 + B2). CI all green: Playwright smoke 3/3 against rebranded preview in 1m4s, forbidden-cors-headers pass, forbidden-endpoints pass, Screenshot diff pass, Vercel deployment complete. Cross-validation lineage: 4th convoy where the same 3-test smoke spec defends auth surface through sweeping change (after PR #15 Layout default-user, PR #19 CORS, PR #20 rate-limit, now this PR #21 brand rename). OPERATOR POST-MERGE ACTION REQUIRED: run 'node scripts/migrations/2026-05-24-rename-admin-email.js' against prod Neon DB before next admin login (ordering: migration FIRST, then any subsequent setup-db invocation). Migration is ESM, idempotent, UNIQUE-collision-safe. PR #21 architect-commit 50ce9ab, B1 ac8c998, B2 1c18d21.
2026-05-25 03:28:29 -04:00
|
|
|
- Email: `bob@deckhearth.com`
|
fix(scripts): require TEST_USERS_PASSWORD + purge weak literals from test-user helpers (#27)
`scripts/create-test-users.js` hardcoded `bcrypt.hash('alice123', 12)`
+ `bcrypt.hash('bob123', 12)` and echoed those literals back to stdout
both per-user and in a final summary block. `TESTING_GUIDE.md`'s Test
Accounts table documented the same `admin123` / `alice123` / `bob123`
trio. These were the last two weak-credential surfaces left in the
helper-script + manual-QA-doc tree after `drop-public-setup` (commits
`ff80753` + `b63b509`) and `fix-reset-db-script` (squash `3ab9bf8`,
PR #25) closed the `setup-neon-db.js` and `reset-db.js` halves of the
umbrella `purge-weak-creds-from-helpers` queued follow-up.
The fix mirrors the post-`drop-public-setup` `setup-neon-db.js`
pattern and the post-PR-#25 `reset-db.js` pattern verbatim, with one
deliberate simplification: a single `TEST_USERS_PASSWORD` env var
covers both alice + bob rather than per-user env vars (risk R2 in the
convoy file argues this — these are fixture users for the
collaboration demo flow, not independent identities, and per-user
sprawl would double the env-var contract for zero security benefit).
`createTestUsers()` now reads `process.env.TEST_USERS_PASSWORD` at the
top of the function body and exits with code 1 BEFORE opening any DB
connection if the var is unset or whitespace-only, with the same
helpful-error wording template the other two scripts use (names the
var, points at `.env.local`, suggests `openssl rand -base64 24`,
references README's "First-time admin setup" section). All four
password-echo `console.log` lines are deleted; the new summary
documents *where* the password comes from without ever printing it.
`TESTING_GUIDE.md`'s Test Accounts table is rewritten to show password
source per user instead of the literal value; the two inline
`Password: alice123` / `Password: bob123` workflow snippets are
replaced with placeholder text. Unlike the previous two convoys, no
CJS→ESM conversion was needed — `create-test-users.js` was already
top-level ESM.
Verification (all static — script is destructive and not live-tested):
`node --check scripts/create-test-users.js` exit 0; `npm run lint` 128
problems (baseline preserved, no regression); `npm run test:run` 21/21
pass; grep `scripts/ TESTING_GUIDE.md` for
`admin123|password123|test123|alice123|bob123` → 0 hits;
`TEST_USERS_PASSWORD` referenced 10 times total (5 script + 5 doc).
Operator caveat: anyone running `node scripts/create-test-users.js`
post-merge must add `TEST_USERS_PASSWORD=<value>` to their
`.env.local` first; existing alice + bob rows in already-seeded
environments are NOT rotated by re-running this script
(`ON CONFLICT (email) DO NOTHING` preserves the old hashes). Same
caveat that applies to the `drop-public-setup` admin row.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:53:24 -04:00
|
|
|
- Password: `<value of TEST_USERS_PASSWORD from .env.local>`
|
2025-07-25 12:28:04 -04:00
|
|
|
|
|
|
|
|
### 6. **Accept Invitation (Simulated)**
|
|
|
|
|
Since we're testing locally, simulate email acceptance:
|
|
|
|
|
- Go to: `/invite/accept?token=MOCK_TOKEN`
|
|
|
|
|
- Or manually add Bob to Alice's collection via database
|
|
|
|
|
|
|
|
|
|
### 7. **Test Collaboration**
|
|
|
|
|
As Bob:
|
|
|
|
|
- Go to `/collections` - should see Alice's collection
|
|
|
|
|
- Open Alice's collection
|
|
|
|
|
- Add more cards using Quick Add
|
|
|
|
|
- See Bob's activity in collaboration panel
|
|
|
|
|
|
|
|
|
|
### 8. **Test Permission Levels**
|
|
|
|
|
- Bob can add/edit cards (Collaborator role)
|
|
|
|
|
- Bob cannot delete collection (only Alice can)
|
|
|
|
|
- Collection shows as "Public" but editing requires invitation
|
|
|
|
|
|
|
|
|
|
## 🔧 Quick Database Commands
|
|
|
|
|
|
|
|
|
|
### Add Bob to Alice's Collection Manually:
|
|
|
|
|
```sql
|
|
|
|
|
-- Get collection ID (usually 1 for first collection)
|
|
|
|
|
SELECT id FROM collections WHERE name LIKE '%Alice%';
|
|
|
|
|
|
|
|
|
|
-- Add Bob as collaborator
|
|
|
|
|
INSERT INTO collection_permissions (collection_id, user_id, role, status)
|
|
|
|
|
VALUES (1, 3, 'editor', 'active');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Check Users:
|
|
|
|
|
```bash
|
|
|
|
|
node scripts/list-users.js
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 🎯 What to Test
|
|
|
|
|
|
|
|
|
|
### ✅ Collection Management:
|
|
|
|
|
- [x] Create collection with image and visibility
|
|
|
|
|
- [x] Real-time stats (card count, value)
|
|
|
|
|
- [x] Only see your own collections initially
|
|
|
|
|
|
|
|
|
|
### ✅ Card Management:
|
|
|
|
|
- [x] Search and add cards via Quick Add
|
|
|
|
|
- [x] Real card data with images and prices
|
|
|
|
|
- [x] Collection value updates automatically
|
|
|
|
|
|
|
|
|
|
### ✅ Collaboration:
|
|
|
|
|
- [x] Invite collaborators with email
|
|
|
|
|
- [x] Permission indicators throughout UI
|
|
|
|
|
- [x] Activity logging for all changes
|
|
|
|
|
|
|
|
|
|
### ✅ User Experience:
|
|
|
|
|
- [x] Beautiful empty states with guidance
|
|
|
|
|
- [x] Real-time search with dropdown results
|
|
|
|
|
- [x] Success confirmations and navigation
|
|
|
|
|
- [x] Permission-based UI elements
|
|
|
|
|
|
|
|
|
|
## 🚀 Ready to Test!
|
|
|
|
|
|
|
|
|
|
The system now provides a complete, real-world testing environment with:
|
|
|
|
|
- Real user authentication
|
|
|
|
|
- Database-driven collections and cards
|
|
|
|
|
- Working collaboration system
|
|
|
|
|
- Beautiful UX with proper empty states
|
|
|
|
|
- Permission-based access control
|
|
|
|
|
|
|
|
|
|
Start testing by logging in as Alice and creating your first collection! 🎮
|