Commit graph

45 commits

Author SHA1 Message Date
Randall Stillwell
1cc2e28423 Migrate Deck Hearth off Vercel/Neon to homelab Dokploy stack.
Replace @vercel/postgres, Blob, and Upstash with lib/sql.js, MinIO object
storage, and CT 102 Redis rate limits. Add Dockerfile for Dokploy deploy,
homelab runbooks, Neon data-copy helper, and point CI smoke/visual at the
homelab URL instead of Vercel previews.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-15 09:32:13 -05:00
varutasu
8f09ed1ef6
feat(scanner): Layer-0 visual catalog search (Phase 3) (#160)
Add pgvector embeddings on cards, server-side cohere/embed-v4.0 via AI
Gateway, kNN identify route, and L0→L1→L2 client orchestration with
empty-index fast escalate and id-cursor backfill job.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 21:46:39 -05:00
varutasu
71757faa90
chore: sync agent pipeline v0.6.0 (keep local L1/L3) (#154)
* Sync agent pipeline artifacts to 0.6.0.

Add model routing defaults, L2 role updates, convoy telemetry, and manifest tracking without touching unrelated in-progress work.

* Record tcg-vault interactive sync (kept local L1/L3 customizations).

Update last_synced_at after reviewing behind/conflict artifacts; no overwrites applied.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 11:27:33 -05:00
Randall Stillwell
ec9bb2b93e feat(catalog): unified multi-game bulk sync + schema map update
Ship Pokemon and Lorcana bulk import libs/scripts, unified weekly cron
sync across MTG/Pokemon/Lorcana with per-game error isolation and
catalog_sync_log telemetry. Admin UI adds Unified/Incremental/Bulk MTG modes.

- Rename reconcile migrations to 1781442330* timestamps so they apply
  after bulk-data migrations without node-pg-migrate ordering conflicts
- Add Lorcana set-code normalization + orphan cleanup migrations
- Drop stricter user_cards_user_card_unique (keep 3-column foil unique)
- Update docs/SCHEMA_MAP.md for tags, card_tags, catalog_sync_log, bulk columns

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 08:22:19 -05:00
Randall Stillwell
67073aab7f feat(catalog): Scryfall bulk data import + Tagger community tags
Add full Scryfall bulk data pipeline:

- Migration: 13 new columns on `cards` (oracle_id, illustration_id,
  color_identity, keywords, legalities, flavor_text, artist, released_at,
  layout, edhrec_rank, reserved, reprint, finishes) with GIN indexes
  for JSONB search.
- Migration: `tags` + `card_tags` tables for Tagger community data.
- Script: `bulk-import-scryfall.js` — downloads Oracle Cards bulk file
  (168 MB) and upserts all 36k+ MTG cards with rich metadata.
- Script: `import-scryfall-tags.js` — imports oracle tags (4.5k tags,
  227k taggings) and art tags (11k tags, 458k taggings).
- Lib: `bulk-sync.js` — runtime bulk sync callable from the admin API.
- Admin UI: mode toggle (incremental vs bulk) on catalog sync panel.

Enables Commander deck validation (color_identity), format legality
checks, keyword search, EDHREC popularity ranking, and functional
card tagging ("removal", "ramp", "draw") for deck building assistance.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 07:51:39 -05:00
varutasu
f83d71abe0
convoy: scripts/rotate-admin-password.js — one-shot admin rotation (rotate-default-admin) (#141)
Closes the operator caveat from the `drop-public-setup` convoy: deployed
envs that ran `npm run setup-db` BEFORE `ff80753` (2026-05-22) still
carry the historical `admin123` bcrypt hash. The seed is idempotent
(`ON CONFLICT (email) DO NOTHING`), so re-running setup-db is a no-op
on existing rows.

## Design — D1: which option from the 3-option menu?

| Option | Picked? | Why |
|---|---|---|
| A. Close as no-op (defer rotation to manual app login) | No | Leaves a real-world residue if any pre-drop-public-setup env still exists — and an audit is harder than just shipping the script. |
| B. One-shot parameterized rotation script | **Yes** | Tightly scoped (~120 lines). Audit-trail-preserving (`updated_at` bump). Reusable for future rotations. No new auth surface in the app. |
| C. First-login forced password reset flow in the app | No | Right product answer, but heavier scope (new route, new flag column, UI work). Deferred as the queued `force-admin-password-reset-flow` convoy. |

## Script shape

`scripts/rotate-admin-password.js`:

- Reads `POSTGRES_URL` + `ADMIN_NEW_PASSWORD` from env (or `.env.local`).
- Optional `ADMIN_EMAIL` override; defaults to `admin@deckhearth.com`.
  Pass `admin@tcgvault.com` for envs that pre-date `pick-a-name`
  (squash `9abbab6`, 2026-05-24).
- Fail-loud-exits BEFORE opening any DB connection if:
  - `POSTGRES_URL` is unset
  - `ADMIN_NEW_PASSWORD` is unset or empty
  - `ADMIN_NEW_PASSWORD` is shorter than 12 chars
- Validates the target row EXISTS AND has `role = 'admin'` before
  touching it. Refuses to rotate non-admin rows even if `ADMIN_EMAIL`
  points at one. Refuses to rotate when multiple rows match (impossible
  given the UNIQUE(email) constraint, but checked anyway).
- Hashes with bcryptjs at 12 rounds — same as `setup-neon-db.js`.
- After UPDATE, re-fetches the row and runs `bcrypt.compare(newPassword,
  row.password_hash)`; exits non-zero if the compare fails (extremely
  unlikely, but catches silent UPDATE failures).
- NEVER echoes the password to stdout / stderr / shell history. The
  only output is the row id, email, role, and updated_at.

Same import shape as the existing `scripts/migrations/2026-05-24-rename-admin-email.js`
(ESM, `dotenv.config({ path: '.env.local' })`, `import { neon } from
'@neondatabase/serverless'`, tagged-template SQL) — keeps the "11
scripts/* using neon() directly" graveyard from gaining new patterns;
fits the `purge-neondatabase-serverless-fully` follow-up convoy's
existing audit shape.

## Out of scope

- Sibling test users (alice / bob in `scripts/create-test-users.js`) —
  dev fixtures, not real auth surfaces. Documented inline + in
  AGENTS.md Gotcha #4.
- First-login forced password reset flow — deferred as the queued
  `force-admin-password-reset-flow` convoy (it's the right product
  answer, but heavier scope than this hygiene PR).
- Email rotation (already handled by
  `scripts/migrations/2026-05-24-rename-admin-email.js`).

## Test plan

- [x] `node --check scripts/rotate-admin-password.js` — syntax OK
- [x] `npm run lint` — clean (1 pre-existing unrelated warning)
- [x] `npm run test:run` — 118 tests pass
- [ ] CI on this PR
- [ ] Operator-side smoke test (NOT covered by CI):
  - Set `ADMIN_NEW_PASSWORD=test-rotation-12chars` against a throwaway
    Neon branch DB, run the script, log in via the app with the new
    password, run the script again with a different password, log in
    again. Skip if there's no convenient throwaway DB.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-12 23:23:44 -05:00
varutasu
8262fec3e8
Remove dead Lorcana import route and CLI script (#59)
* Remove dead Lorcana import route and CLI script

The admin card-import UI never wired Lorcana; catalog sync uses
pages/api/admin instead. Drop the unused API route, CLI helper, and
stale docs references to import-lorcana.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Remove orphaned import-lorcana-simple CLI script.

It POSTed to the deleted /api/cards/import-lorcana endpoint; no remaining callers.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 00:42:18 -05:00
varutasu
5115683ead
Purge direct @neondatabase/serverless dependency from operational scripts. (#57)
Migrate setup-neon-db.js and reset-db.js to @vercel/postgres tagged templates so the runtime uses a single SQL client; historical add-*/fix-*/seed-* scripts remain unchanged per no-go-zone.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 00:42:11 -05:00
varutasu
174a370fc3
Switch Pokémon catalog import to pokemon-tcg-data on GitHub. (#52)
Replace pokemontcg.io API discovery and import with raw JSON from PokemonTCG/pokemon-tcg-data; format collector numbers as number/printedTotal and drop the API key dependency for catalog sync.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 11:56:01 -05:00
varutasu
0a47362103
feat(catalog): weekly Vercel Cron sync for MTG and Pokémon sets (#48)
Extract shared import logic into lib/card-import, discover missing sets via
Scryfall/Pokémon TCG APIs, and expose GET /api/cron/sync-catalog protected
by CRON_SECRET (max 3 sets/run, paced imports).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 14:59:59 -05:00
varutasu
de9f3348f6
feat(infra): adopt node-pg-migrate + backfill initial schema migration (#32)
Closes P1 #11 of .convoys/ship-readiness.md (launch sequence step 7) —
"No migration tool — scripts/add-*.js graveyard". Schema changes
post-this-convoy ship as node-pg-migrate migrations under migrations/
at the repo root; the legacy 27 scripts/add-*.js / scripts/fix-*.js /
scripts/seed-*.js jobs remain append-only history per the no-go-zones
rule.

Decisions (full record in .convoys/migration-tool.md § Decisions):

D1 — Tool: node-pg-migrate@^8. Rejected drizzle-kit / prisma migrate /
kysely because each forces broader TypeScript surface than AGENTS.md
Gotcha #9 allows (TS is a devDep only). node-pg-migrate is
JavaScript-native, raw-SQL-friendly via pgm.sql(), and ESM-clean for
the post-bump-next-js "type": "module" repo. Brings pg@^8.21.0 as a
peer dep (dev-only; never loaded in the Next.js bundle).

D2 — Migrations directory: migrations/ at the repo root. Separates
the tool-wrapped artifacts from the historical scripts/migrations/
placeholder folder (which housed the lone pre-tool
2026-05-24-rename-admin-email.js migration and remains preserved for
the audit trail). Matches node-pg-migrate's default flag.

D3 — Tracking table: default pgmigrations (no name collision with
the existing 7-table bootstrap; zero CLI noise).

D4 — Backfill strategy: hand-translate scripts/setup-neon-db.js's
DDL into the initial migration verbatim. Each await sql`...` block
becomes one pgm.sql(`...`) call. Each CREATE uses IF NOT EXISTS, so
the migration is idempotent against fresh AND pre-existing envs —
re-running setup-db on an env that already has the schema is a no-op
DDL-wise (only records the pgmigrations row). Documented assumption:
prod has drifted via the 27 historical add-*.js scripts; reconciling
those into the migration history is the queued
reconcile-historical-add-scripts follow-up convoy.

D5 — Bootstrap reconciliation: split. setup-neon-db.js now (1)
validates ADMIN_INITIAL_PASSWORD + POSTGRES_URL, (2) spawns
`npm run migrate up` via child_process with stdio inherited, (3)
seeds the admin row with ON CONFLICT (email) DO NOTHING. The seven
DDL blocks are deleted from setup-neon-db.js; success/error message
copy is updated to mention the migration step explicitly.

D6 — CI integration: defer. Wiring a CI job that runs migrate up
against a test DB needs either a dedicated Neon branch + secret OR a
Postgres service container; both are real work. Surface as
wire-migrate-into-ci follow-up. Risk acknowledged in
.convoys/migration-tool.md § R3.

D7 — Down-migration on the initial backfill: hard stub. Rolling back
the initial schema would drop every user / card / collection / deck
row in the DB. The stub throws with a long-form error pointing at
the recommended alternative (branch the Neon database + forward-apply).
Future migrations that touch one of the seven bootstrap tables write
their own dated migration with a real down().

Verification (pre-PR):
- npm run lint → 128 problems (baseline preserved, zero regression;
  migration file is lint-clean, no new ignore patterns)
- npm run test:run → 21/21 pass
- node --check on migrations/1779853647564_initial-schema.js + on
  scripts/setup-neon-db.js → exit 0
- Module load + down() throw verified via dynamic import
- npm run migrate -- --help reaches the node-pg-migrate CLI through
  the wrapper

Live verification against a Neon branch is deferred (no throwaway
branch available); the operator's optional post-merge sequence is
documented in .convoys/migration-tool.md § Operator runbook.

See .convoys/migration-tool.md § Follow-ups for the queued
wire-migrate-into-ci / reconcile-historical-add-scripts /
retire-graveyard-scripts-after-audit / audit-node-pg-migrate-transitive-deps
/ add-migration-template follow-up convoys.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:01:58 -05:00
varutasu
5f2b234cc8
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 22:53:24 -05:00
varutasu
3ab9bf840c
fix(scripts): convert reset-db.js to ESM + require ADMIN_INITIAL_PASSWORD (#25)
Fold of two queued follow-ups from pick-a-name architect audit
(convert-reset-db-to-esm + purge-weak-creds-from-helpers). Three bugs
in one file; all three fixed atomically by mirroring the proven post-
drop-public-setup setup-neon-db.js shape (commit b63b509).

Bugs fixed:
1. CJS-in-ESM (lines 10, 12, 142): require('dotenv'), require('@neon...'),
   inline require('bcryptjs'). package.json has "type": "module" since
   bump-next-js, so npm run reset-db threw ReferenceError on Node 22.x.
   Same bug pattern that hit setup-neon-db.js pre-drop-public-setup B2.
2. Hardcoded weak admin password (line 143: bcrypt.hash('admin123', 12)).
   Same anti-pattern drop-public-setup B1 removed from setup-neon-db.js.
3. Password echoed to stdout (line 156: console.log('Admin Password:
   admin123')). Security anti-pattern; setup-neon-db.js post-DPS does
   NOT echo passwords.

Fix shape (verbatim mirror of setup-neon-db.js):
- ESM top-level imports (dotenv, neon, bcrypt)
- Fail-loud ADMIN_INITIAL_PASSWORD env-var check at function top with
  helpful error message pointing to README "First-time admin setup"
- bcrypt.hash(adminPassword, 12) instead of literal
- ON CONFLICT (email) DO NOTHING on INSERT (defensive against
  double-run, matches setup-neon-db.js line 149)
- No password echo in success block; admin email logged for confirmation
- Updated docstring to flag DESTRUCTIVE + reference required env

Convoy file: .convoys/fix-reset-db-script.md (P2 hygiene, parent-owned,
no architect — this is a proven-pattern fold with no new decisions
to ratify).

Verification:
- node --check scripts/reset-db.js: exit 0
- npm run lint: 128 problems (baseline preserved, no regression)
- npm run test:run: 21/21 pass
- Grep: 0 require( | 0 admin123 | 0 'Admin Password' in scripts/reset-db.js
- Grep: 3 ADMIN_INITIAL_PASSWORD references (docstring, const, error msg)

NOT live-tested (script is destructive — drops all tables). Operator
can optionally run npm run reset-db against a non-prod Neon branch
post-merge to verify end-to-end.

Surfaces follow-up: lint-against-cjs-in-esm-scripts (P3 polish — add
ESLint rule to prevent any future require() in scripts/** under
"type": "module"). Surfaced for future convoy queue.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 22:08:45 -05:00
varutasu
1de0e03522
fix(migration): rename-admin-email crashes — neon() returns array, not { rows }
Hotfix to scripts/migrations/2026-05-24-rename-admin-email.js (shipped 2026-05-24 in pick-a-name PR #21). Script crashed on first invocation with 'TypeError: Cannot read properties of undefined (reading length)' at line 44. Root cause: architect designed against @vercel/postgres return shape { rows, rowCount } but the script uses @neondatabase/serverless's neon() tagged template which returns the rows array directly. AGENTS.md Gotcha #1 (two SQL clients in parallel) is exactly this kind of cross-contamination. Fix: drop the { rows: x } destructuring in all 3 sites + add a 4-line why comment block above the first site so the next migration author doesn't repeat. Verified hand-run against prod Neon DB: migrated 3 users (admin id=1, alice id=5, bob id=6) from @tcgvault.com to @deckhearth.com; idempotent re-run prints 'Nothing to migrate.' No data risk on the original crash — script exited at line 44 before reaching the UPDATE at line 54. PR #21 operator action item now complete in prod. Surfaces a P3 follow-up: add-neon-return-shape-rule (or fold into single-sql-client). All CI green: lint 128 baseline, vitest 21/21, Playwright smoke 3/3 in 1m2s, forbidden-cors-headers pass, forbidden-endpoints pass. PR #24, commit 98406fa.
2026-05-25 11:30:09 -05:00
varutasu
9abbab6c21
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 02:28:29 -05:00
Randall Stillwell
b63b5090cc fix(seed): convert scripts/setup-neon-db.js from CJS to ESM (Node 22.x compat)
Brief 2 of drop-public-setup. Closes Decision D — pure module-system
conversion of scripts/setup-neon-db.js so `npm run setup-db` actually
runs on Node 22.x where package.json has "type": "module" (added by
bump-next-js for ESLint v9 flat-config support).

Before this commit, `npm run setup-db` threw:
  ReferenceError: require is not defined in ES module scope

After this commit, brief 1's ADMIN_INITIAL_PASSWORD env-var gate actually
fires as documented.

Changes (all in scripts/setup-neon-db.js):
  - require('dotenv').config(...) → import dotenv + dotenv.config(...)
  - require('@neondatabase/serverless') → import { neon }
  - inline require('bcryptjs') hoisted to top-of-file import bcrypt
  - no functional changes; same DDL, same env-var gate, same console.logs

Smoke verification: see PR description.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 17:02:44 -05:00
Randall Stillwell
ff80753fe4 feat(seed): require ADMIN_INITIAL_PASSWORD env var; strip admin123 from README
Closes P0 #3 from .convoys/ship-readiness.md.

scripts/setup-neon-db.js:
  - Read ADMIN_INITIAL_PASSWORD env var at the top of setupNeonDatabase()
    before any DB connection. Fail loudly (process.exit(1)) with an
    actionable message if unset or empty.
  - Replace bcrypt.hash('admin123', 12) with bcrypt.hash(adminPassword, 12).
  - Delete the two console.log lines that echoed admin user + password to
    stdout (R3 - stdout leak into CI logs).
  - Keep ON CONFLICT (email) DO NOTHING unchanged. Re-running setup-db
    on an env with the admin row already present is a no-op for the
    password (R4 - silent rotation prevention). Rotation of existing
    weak-hash admin rows is out of scope (Decision A - queued for the
    rotate-default-admin follow-up convoy).

README.md:
  - Add ADMIN_INITIAL_PASSWORD to the install-step env-example block
    with a CI-secret note (and add KV_REST_API_URL/KV_REST_API_TOKEN
    for completeness; they're optional for local dev).
  - Replace the "Default Admin Account" section with "First-time
    admin setup", documenting the env var, openssl rand suggestion,
    and the operator rotation note for envs that predate this change.
  - Zero occurrences of 'admin123' remain in README.md (the operator
    rotation note refers to "the prior weak default" instead of naming
    the literal string, so grep verification A2 holds).

Decisions A1 (going-forward only), B (operational change allowed),
C1 (no vitest coverage - manual smoke in PR description) per
.convoys/drop-public-setup.md section Decisions.

Smoke output: see PR description.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 17:02:44 -05:00
Randall Stillwell
1944b1ed48 bootstrap: agent pipeline v0.5.0 + ship-readiness review
Installs the three-layer agent-pipeline scaffold (https://github.com/varutasu/agent-pipeline @ v0.5.0):

L1 — Context (curated brain)
- AGENTS.md: orientation, conventions, 8 explicit gotchas
- .cursor/rules/: no-go-zones, api-routes, auth-and-permissions,
  db-and-schema, ui-and-theming, schema-map
- .cursor/skills/: add-api-route, add-page recipes
- docs/agent-context/README.md: layer explainer
- docs/SCHEMA_MAP.md: hand-curated Neon Postgres reference
  (replaces Prisma schema map since stack is raw SQL)

L2 — Subagent roles (copied verbatim from upstream templates)
- 9 .cursor/agents/role-*.md files: Conductor, IA-Architect,
  UX-Reviewer, Architect, Implementer, Reviewer,
  Design-System-Auditor, A11y-Auditor, Doc-Writer

L3 — Pipeline scaffolding (Vercel variant)
- CI: lint + schema-map-drift only (no duplicate build —
  Vercel handles it). Test job commented out until vitest lands.
- preview-smoke + visual-diff via wait-for-vercel-preview
- pr-health-rollup sticky comment aggregator
- agent-context-drift weekly cron
- PULL_REQUEST_TEMPLATE, CODEOWNERS (auth/admin paths tagged)
- .convoys/ folder + seed ship-readiness.md review
- lib/flags/index.js (JS — converted from TS template)
- scripts/wt.sh (Cursor 3.2 deprecation stub),
  scripts/log-convoy-event.sh
- tests/smoke/app.smoke.spec.ts (Playwright skeleton)

Manifest
- .agent-context-manifest.yml: tracks 31 artifacts by sha256
  for future sync-agent-context drift detection

Review
- .convoys/ship-readiness.md: 16 findings (7 P0 ship-blockers,
  5 P1 quality-bar, 4 P2 refactor, P3 UX/IA/a11y/docs) with
  proposed 13-convoy launch sequence.

No production code changed in this commit. All findings in
the ship-readiness review will be addressed in follow-up convoys
starting with fix-auth-bypass.

Structural brain: user-code-review-graph MCP has indexed the
codebase (122 files, 628 nodes, 5602 edges, 11 communities,
84 flows). Per-developer; not committed.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 02:31:26 -05:00
Randall Stillwell
afb79c57d9 Major Scanner Improvements
🔧 Gemini AI Integration:
- Added Google Gemini API as default OCR service
- Auto-configures from GEMINI_AI_API_KEY environment variable
- Fixed Puter.js authentication issues
- Enhanced OCR settings with connection testing

🎨 Redesigned Scanner Queue:
- New thumbnail + content layout with checkbox overlay
- Smart quantity management (duplicates increment quantity)
- Complete card information display from database
- Two-row action layout (primary/secondary actions)
- Floating bottom toolbar for bulk actions
- Real card images from database

�� Enhanced User Experience:
- Fixed Canvas2D performance warnings
- Better error handling and fallbacks
- Improved responsive design
- Database confirmation indicators
- Professional card scanning workflow

📱 Mobile Ready:
- Optimized layouts for mobile scanning
- Touch-friendly controls and interactions
- Improved visual feedback and status indicators
2025-07-29 14:19:48 -05:00
Randall Stillwell
b3240dbb3c 🎨 Enhanced Signup with Username & Profile Images
 New Signup Features:
- Added username field with validation (3+ chars, alphanumeric + underscore)
- Profile image upload with file validation (5MB max)
- DiceBear Adventurer Neutral API integration for random avatars
- Generate new random avatar button with dice emoji
- Initial random avatar generation on page load

🔧 Backend Updates:
- Updated registration API to handle all new fields
- Username uniqueness validation with specific error messages
- Profile image URL storage in database
- Enhanced user response with all profile data

🗄️ Database Migration:
- Added first_name, last_name, username, profile_image_url columns
- Unique constraint on username field
- Migration script with existing user updates
- Default values for existing accounts

🎯 User Experience:
- Real-time form validation with error states
- Loading states for image upload/generation
- File type and size validation
- Clean profile image preview with rounded borders
- Consistent styling with existing theme

Ready for enhanced user profiles! 🚀
2025-07-28 11:18:58 -05:00
Randall Stillwell
4689424f3a 🔧 Fix System Collections & Database Schema Issues
🐛 Database Schema Fixes:
- Removed non-existent 'updated_at' column from collection_cards operations
- Fixed SQL queries in card ownership API and seeding scripts
- Resolved column does not exist errors

🚫 Hide System Collections from Selection:
- Added 'excludeSystem' parameter to /api/collections endpoint
- Updated CollectionSelectionModal to exclude system collections
- 'All My Cards' no longer appears in card addition modals

 Enhanced System Collection Styling:
- Upgraded system collection badge with gradient styling
- Added 🔒 SYSTEM badge with blue-purple gradient
- Added informative tooltip: 'Automatically syncs with your owned cards'
- Made system collections visually distinct and educational

🎯 User Experience Improvements:
- System collections are now clearly identified as special
- Users understand they can't manually add cards to system collections
- Better visual hierarchy and information architecture
- Automatic sync behavior is now clearly communicated

Card ownership should now work without errors! 🚀
2025-07-27 19:17:55 -05:00
Randall Stillwell
9d7278f8f5 🔧 Fix Card Ownership & Auto-Sync with 'All My Cards'
🐛 Database Fixes:
- Added unique constraint on user_cards (user_id, card_id)
- Added unique constraint on collection_cards (collection_id, card_id)
- Fixed ON CONFLICT clauses in card ownership API

 Auto-Sync Feature:
- Card ownership now automatically syncs with 'All My Cards' collection
- When user marks card as owned → added to system collection
- When user removes ownership → removed from system collection
- Real-time bidirectional sync between user_cards and collection_cards

🔄 Migration Script:
- Cleaned up any duplicate entries
- Added necessary database constraints
- Synced existing owned cards (0 users had existing data)

🎯 API Improvements:
- Simplified card ownership API (removed GET method)
- Better error handling and validation
- Clear success messages for user feedback
- Automatic collection management

Card ownership should now work perfectly! 🚀
2025-07-27 15:21:43 -05:00
Randall Stillwell
603bf5bc89 🔒 Implement 'All My Cards' System Collection
 New Feature - Automatic System Collection:
- Every user gets an undeletable 'All My Cards' collection on registration
- Contains all cards marked as owned by the user
- Cannot be deleted, renamed, or made public
- Special 🔒 System indicator in the UI

🗃️ Database Changes:
- Added is_system_collection column to collections table
- Migration script created 'All My Cards' for all existing users (5 users)
- Automatic creation in registration API for new users

🛡️ API Protections:
- DELETE: System collections cannot be deleted
- PUT: System collections cannot be renamed or made public
- Added isSystemCollection field to API responses

🎨 Frontend Updates:
- System collections show 🔒 System badge
- Edit/Delete buttons hidden for system collections
- Special visual indicator for protected collections

🎯 Implementation Details:
- Unique slug generation (all-my-cards, all-my-cards-2, etc.)
- Proper permissions setup for each collection
- Error handling for edge cases
- Non-blocking registration if collection creation fails

Ready for users to have their automatic 'All My Cards' collection! 🚀
2025-07-27 15:17:51 -05:00
Randall Stillwell
fec6c99d42 🎮 Create Comprehensive Collection Seeding Script
 New Features:
- Created seed-collections-with-cards.js for testing thumbnail layouts
- Seeds database with collections in 3 different states:
  😢 Empty collections (crying emoji placeholder)
  🃏 Collections with cards (white card boxes with images)
  🖼️ Collections with custom thumbnails (uploaded images)

🗂️ Sample Data Created:
- 13 sample cards (MTG, Pokemon, Lorcana with real images)
- 6 collections total (3 for Alice, 3 for Bob)
- Mix of public/private collections with realistic content
- Proper slug generation and permissions setup

🎯 Test Coverage:
- Alice: Power 9 Collection (cards), Pokemon Starters (custom thumb), Empty Future (crying emoji)
- Bob: Budget MTG (cards), Lorcana Heroes (custom thumb), Secret Project (1 card)
- All collections have proper tags, descriptions, and ownership

🔧 Technical Implementation:
- Fixed SQL result structure for Neon database (.rows vs direct array)
- Handles existing cards gracefully (check before insert)
- Generates unique slugs for all collections
- Creates proper permissions and collection_cards relationships

Ready to test all thumbnail layout variations! 🎨
2025-07-27 14:26:35 -05:00
Randall Stillwell
e4ea9b4e73 🎭 Add Collection Seeding Script for Alice & Bob
 Created Comprehensive Collection Seeding:
- Wipes all existing collections cleanly
- Seeds 4 collections for Alice (vintage MTG, modern decks, Pokemon, Lorcana)
- Seeds 5 collections for Bob (commander, standard, rare Pokemon, Japanese, budget)
- Generates proper URL slugs for all collections
- Creates proper ownership permissions

🎨 Alice's Collections (4):
- Alice's Vintage MTG Collection (Public) - Power 9 & vintage cards
- Modern Competitive Decks (Private) - Tournament-ready decks
- Pokemon Base Set Complete (Public) - Complete 1998 base set
- Disney Lorcana Treasures (Private) - Beautiful Disney characters

🎮 Bob's Collections (5):
- Bob's Commander Arsenal (Public) - EDH multiplayer decks
- Standard Rotation Collection (Private) - Current standard cards
- Rare Pokemon Cards (Public) - First editions & promos
- Japanese Exclusive Cards (Private) - Unique Japanese artwork
- Budget Deck Collection (Public) - Beginner-friendly decks

🔧 Technical Features:
- Proper user ownership (Alice ID: 5, Bob ID: 6)
- Mix of public/private collections for testing
- Realistic descriptions and tags
- Clean database wipe before seeding
- URL-friendly slug generation

Perfect for testing authentication, permissions, and collection management! 🎯
2025-07-27 12:26:55 -05:00
Randall Stillwell
50a3156b92 🔗 Implement Collection Slug URLs
🎯 Vanity URLs for Collections:
- Added slug-based URLs like /collection/modern-masters-2021
- Backwards compatible with numeric IDs
- SEO-friendly and memorable URLs

🛠️ Slug System:
- Created lib/slug-utils.js with slug generation and validation
- generateSlug() converts names to URL-friendly format
- generateUniqueSlug() handles duplicates with numeric suffixes
- isValidSlug() validates format (lowercase, hyphens, no special chars)

📊 Database Schema:
- Added slug column to collections table with unique constraint
- Migration script adds slugs to existing collections
- Database constraints ensure slug format and uniqueness
- Performance index on slug column

🔌 API Updates:
- Updated collections API to generate slugs for new collections
- New [identifier].js endpoint handles both slugs and IDs
- Thumbnails API supports both slug and ID lookups
- Smart identifier detection (slug vs numeric ID)

🎨 Frontend Integration:
- Collections page uses slugs for navigation
- Fallback to ID if slug not available (backwards compatibility)
- Updated all collection links to use slugs
- Sample collections created with proper slugs

 URL Examples:
- /collection/modern-masters-2021 (new slug format)
- /collection/123 (old ID format still works)
- Automatic redirect potential for future

The collection URLs are now beautiful and shareable! 🚀
2025-07-26 22:06:52 -05:00
Randall Stillwell
afec905856 🎯 Build Comprehensive User Profile & Settings System
👤 Profile Page Features:
- Complete user profile with avatar, name, username, bio, and email
- Avatar upload with file validation (5MB limit, image types only)
- Avatar generation functionality for custom avatars
- Favorite games selection (MTG, Pokemon, Lorcana)
- Collection statistics display (total cards, collections, decks, value)
- Profile editing with real-time validation
- Member since date and role display

⚙️ Settings Page Features:
- Multi-section tabbed interface (Account, Security, Preferences, Notifications, Display)
- Account settings: email (read-only), collection visibility, preferred currency
- Security settings: password change with validation, 2FA toggle, account deletion
- Preferences: cards per page (25/50/100), default view (grid/list)
- Notifications: email notifications, marketing emails (toggle switches)
- Display settings: theme (light/dark/system), language selection

🗄️ Database Schema Updates:
- Added user profile fields: first_name, last_name, username, bio, avatar_url
- Added preference fields: favorite_games (JSONB), collection_visibility, preferred_currency, cards_per_page, default_view
- Added notification settings: notifications_email, notifications_marketing, two_factor_enabled
- Added display settings: theme, language
- Created user_settings table for complex settings
- Created user_avatars table for avatar management
- Added performance indexes and data validation constraints

📡 API Endpoints Created:
- GET/PUT /api/user/profile - Profile information management
- GET/PUT /api/user/settings - Settings and preferences management
- PUT /api/user/password - Secure password change with bcrypt validation
- GET /api/user/stats - Collection statistics and analytics

🔒 Security & Validation:
- Password change requires current password verification
- Username uniqueness validation
- Input validation for all enum fields (currency, theme, view mode, etc.)
- Proper error handling and user feedback
- Authentication required for all user endpoints

🎨 UI/UX Features:
- Beautiful fire-themed design matching app branding
- Responsive design for mobile and desktop
- Loading states and success/error messages
- Avatar placeholder with user initials
- Tabbed settings interface with icons
- Toggle switches for boolean settings
- Form validation with helpful error messages

 Additional Features:
- Collection stats with game/rarity breakdowns
- Recent activity tracking
- Danger zone for account deletion with double confirmation
- Member since display with formatted dates
- Currency formatting for collection values
- Game icons and themed styling throughout

The profile and settings system is now fully functional with comprehensive user management! 👨‍💻
2025-07-26 18:05:55 -05:00
Randall Stillwell
faab506b25 Added Collaborator Facepile to Collection Header
🎯 Moved collaboration display from bottom section to hero header:
- Created CollaboratorFacepile component with hover tooltips
- Shows creator + active collaborators in compact format
- Color-coded avatars by role (owner=purple, editor=blue, viewer=green)
- Displays up to 4 faces, then '+N more' for additional collaborators
- Rich hover tooltips showing email and role information
- Responsive text: 'Crafted by X & N others'

🔧 Technical improvements:
- Fixed favorites system database migration (separated SQL commands)
- Fixed favorites API SQL syntax errors
- Integrated facepile into collection metadata section
- Removed redundant CollaborationManager from bottom
- Clean component architecture with proper loading states

🎨 UX enhancements:
- Smooth hover animations with scale effects
- Professional tooltips with arrows
- Proper z-index layering for overlapping elements
- Loading skeleton while fetching collaborators
- Accessible color contrast and typography

Perfect for showing collaboration at a glance! 👥
2025-07-25 22:38:03 -05:00
Randall Stillwell
2a76666f79 🚀 Implemented Complete Collection Functionality
Built out all requested features from top to bottom:

 Upload Modal for Hero Images:
- Created UploadImageModal component with drag-and-drop
- Support for both URL input and file upload
- Live preview and validation
- Integrated into collection detail page

 Smart TCG Tags:
- Dynamic tags showing only games with cards
- Properly positioned under description
- Clean blue rounded styling

 Combined Share & Invite Modal:
- Unified ShareModal replacing separate buttons
- Public access toggle with community visibility
- Email/member search functionality
- Default viewer role for invitations
- Social sharing (Twitter, Facebook, Reddit, Discord)
- User search API endpoint (/api/users/search)

 Comprehensive Favorites System:
- Database schema for cards, collections, and decks
- API endpoint (/api/favorites) for CRUD operations
- Real-time favorite status checking
- Working toggle functionality in UI
- Migration script for database setup

 CSV Download Functionality:
- Complete card metadata export
- Proper CSV formatting with escaping
- All card fields included (name, set, rarity, etc.)
- Automatic filename generation
- Client-side download implementation

🎯 UI/UX Improvements:
- Removed duplicate buttons and switches
- Clean action bar with proper hierarchy
- Working modals with proper state management
- Error handling and loading states

🛠️ Technical Features:
- JWT authentication for all endpoints
- Proper database relationships and indexes
- CORS headers and error handling
- Optimized queries and performance

All todos completed! Ready for full collection management! 🎮
2025-07-25 22:28:52 -05:00
Randall Stillwell
72de168fc6 🎯 Complete Testing Workflow Setup
 Database & API Fixes:
- Fixed collection detail API to use correct column names (card_type, market_price, image_url)
- Removed all mock data and fallbacks
- Updated field mappings throughout collection detail page
- Fixed hero section to use real collection data with proper image support

�� Test Users Created:
- admin@tcgvault.com / admin123 (Admin)
- alice@tcgvault.com / alice123 (User)
- bob@tcgvault.com / bob123 (User)

🃏 Sample Cards Added:
- 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

🔧 Collaboration Features:
- Added CollaborationManager to collection detail page
- Integrated real user permissions (isOwner check)
- Updated hero section with real stats and creator info

🔍 Card Management:
- Created cards search API (/api/cards/search)
- Implemented quick add functionality in empty state
- Real-time card search with dropdown results
- Add cards directly to collection with quantity

�� Ready for Testing:
1. Login as any user to see only their collections
2. Create collections with real data
3. Add cards using search functionality
4. Invite collaborators via email system
5. Switch users to test collaboration workflow

Complete end-to-end testing environment ready! 🚀
2025-07-25 10:42:00 -05:00
Randall Stillwell
af7593d884 Enhanced Collections UI with API Integration
🎯 Collections Page Improvements:
- Removed TCG selection from creation modal
- Added image URL field for collection hero images
- Changed public checkbox to visibility dropdown (Private/Invite-Only/Public)
- Added success modal with navigation to created collection
- Integrated real API calls for creating and fetching collections
- Added Permission indicators throughout the interface

🃏 Collection Detail Page Enhancements:
- Created comprehensive empty state for new collections
- Added 'Browse Cards to Add' call-to-action button
- Included quick add search functionality
- Improved filtered results empty state with clear filters option
- Integrated API calls for real collection data
- Distinguished between empty collection vs no search results

🗄️ Database & API Updates:
- Added image column to collections table
- Updated collections API to handle image field
- Enhanced API to return proper collection data structure
- Added fallback to mock data for development

🎨 User Experience:
- Beautiful success confirmation after collection creation
- Direct navigation to newly created collection
- Clear visual distinction between different empty states
- Intuitive call-to-action buttons for collection building
- Permission badges visible on collection cards

Ready for users to create collections with images and start building their card collections! 🚀
2025-07-25 10:06:39 -05:00
Randall Stillwell
23d995102f 🎉 COMPLETED: Full Collaborative Collections System
 ALL FEATURES IMPLEMENTED:

🔐 Advanced Permission System:
- Role-based access control (Owner/Editor/Viewer)
- Permission middleware for all API endpoints
- Granular permissions for collection operations
- Activity logging for complete audit trails

🌍 Collection Visibility Types:
- Private: Owner-only access
- Invite-Only: Controlled collaboration
- Public: Community accessible
- Dynamic permission checking across all endpoints

📧 Complete Email Integration:
- Beautiful HTML invitation templates
- Role-based permission descriptions
- Personal message support
- Accept/decline workflow with proper UX
- Bulk invitation system for multiple users

🎨 Rich User Interface:
- Permission indicators with tooltips
- Activity log component with real-time updates
- Collaboration management dashboard
- Bulk invite modal with batch processing
- Permission gates throughout the UI

 Performance & Security:
- Database indexes for optimal queries
- Comprehensive error handling
- CORS headers and preflight support
- JWT-based authentication integration
- Cascading deletes and data integrity

🚀 Ready for Production:
- All API endpoints protected with permissions
- Complete activity logging system
- Beautiful email templates with Resend
- Responsive UI components
- Error handling and loading states

This system now provides enterprise-level collaboration features for community-driven collection building! 🎯
2025-07-25 08:34:28 -05:00
Randall Stillwell
be67815cab Added comprehensive user management scripts
- Created list-users.js to display all users with roles and details
- Added promote-user-to-admin.js to elevate regular users to admin
- Added demote-admin-to-user.js with safety check for last admin
- All scripts use proper ES modules and dotenv for environment loading
- Scripts validate user existence and current roles before operations
- Added detailed documentation to scripts/README.md
- Includes user-friendly output with emojis and clear status messages
- Tested promotion functionality successfully
- Maintains database integrity with proper error handling
2025-07-24 20:03:31 -05:00
Randall Stillwell
f27a7333db Created comprehensive admin card editor
- Built complete admin interface for editing all card properties
- Added card search functionality with live results
- Created comprehensive form with sections for:
  * Basic information (name, game, set, rarity, etc.)
  * Game mechanics (type, mana cost, power/toughness, colors)
  * Card text and oracle text
  * Image URLs (primary and stock images)
  * Pricing information (current and market prices)
- Added real-time card preview that updates as you edit
- Implemented PUT API endpoint for updating cards
- Added proper validation and error handling
- Added database schema updates (updated_at column)
- Integrated admin navigation between card editor and import tools
- Full responsive design with modern UI components
- Live search with card thumbnails and metadata
- Proper form state management and data persistence
2025-07-24 15:16:57 -05:00
Randall Stillwell
bb60b4f6b0 Enhanced card detail page with real data and functionality
- Updated card detail page to fetch real data from API
- Added ownership tracking with quantity management
- Added favorite system for cards
- Added collection and deck management functionality
- Created API endpoints for ownership, favorites, collections, and decks
- Added database columns for quantity and favorited status
- Shows current collections and decks the card belongs to
- Added proper error handling and loading states
- Integrated with real card data from database
- Added purchase links to TCGPlayer and eBay
2025-07-24 15:03:09 -05:00
Randall Stillwell
73a0c652b2 Fix card sizing consistency across all TCGs
- Added wrapper div with max-width constraint to ensure consistent card sizes
- Updated image rendering to use object-cover with proper positioning
- Removed maxWidth from Card3D component since it's now handled by wrapper
- Ensures all cards (MTG, Pokemon, Lorcana) have identical dimensions
- Fixed responsive grid layout to maintain consistent card sizes
2025-07-24 14:54:12 -05:00
Randall Stillwell
e046515a38 Add real Lorcana import using Lorcast API
- Replaced mock Lorcana import with real API integration
- Uses Lorcast API (https://api.lorcast.com/v0/cards/search) for comprehensive card data
- Added proper set code mapping (tfc->1, rotf->2, ink->3)
- Includes card images, prices, stats, and detailed metadata
- Created dedicated Lorcana import scripts for standalone use
- Maintains duplicate checking and proper error handling
- Supports all 3 Lorcana sets: The First Chapter, Rise of the Floodborn, Into the Inklands
2025-07-24 12:27:10 -05:00
Randall Stillwell
b6f76297bc Fix import issues: Add retry logic and better error handling
- Added retry logic with exponential backoff for Pokemon API calls
- Created Lorcana import endpoint with placeholder data
- Improved error handling for 504 timeouts and 404 not found errors
- Added longer delays for Pokemon imports to avoid rate limiting
- Enhanced logging for better debugging of import issues
- Fixed response parsing to handle different API response formats
2025-07-24 10:30:21 -05:00
Randall Stillwell
e75a4a6649 Major redesign: Enhanced card display with particle effects, improved filters, and search functionality
- Redesigned card display with 2.5:3.5 aspect ratio and image-only view
- Added infinite scroll to replace pagination
- Implemented authentic card back placeholders for MTG, Pokemon, and Lorcana
- Added rarity-based particle effects with tiered intensity (mythic/enchanted/rare/uncommon)
- Enhanced hover details panel with structured card information
- Fixed search functionality with debouncing and Enter key support
- Improved filter system with working TCG, rarity, set, and price filters
- Added favorite system for cards in both hover and detail views
- Updated card detail page with comprehensive metadata and actions
- Fixed API filtering with proper Vercel Postgres implementation
- Added particle animations and rarity glow effects
- Improved overall UX with better visual hierarchy and interactions
2025-07-23 21:26:54 -05:00
Randall Stillwell
2f94044832 Remove broken migration script that references deleted files 2025-07-23 09:34:37 -05:00
Randall Stillwell
e29728e2be Add Disney Lorcana support via Lorcast API - Complete integration with search, browse, and database population 2025-07-22 20:17:47 -05:00
Randall Stillwell
d21394d579 Add comprehensive card data sources integration with external APIs and database browser component 2025-07-22 20:00:10 -05:00
Randall Stillwell
04d7383025 Add admin promotion options 2025-07-22 07:23:03 -05:00
Randall Stillwell
dc95d0d76d Implement complete user authentication and admin panel system
 Features Added:
- User registration and login with JWT authentication
- Role-based access control (user/admin)
- Comprehensive admin panel with user management
- Password hashing with bcrypt
- Session management and token storage
- Protected routes and public routes
- Modern login/register forms with validation

🗄️ Database Schema:
- Users table with profile information
- Roles and permissions system
- User-role junction tables
- Session management tables
- Database triggers and indexes

🎨 UI/UX Improvements:
- Updated navigation with user menu
- Admin badge and access controls
- Responsive authentication forms
- Loading states and error handling
- Role-based UI elements

🔧 API Endpoints:
- /api/auth/login - User authentication
- /api/auth/register - User registration
- /api/admin/users - User management (admin only)
- /api/setup-auth - Database schema setup

🚀 Admin Panel Features:
- User listing with search and pagination
- Role assignment (user/admin)
- User activation/deactivation
- System dashboard with stats
- Card management placeholder
- Real-time user management
2025-07-21 21:06:38 -05:00
Randall Stillwell
4fea3d287e Add Neon database integration and migration scripts
- Install @neondatabase/serverless, @vercel/blob, @stackframe/stack
- Add database schema setup script (scripts/setup-database.sql)
- Add JSON to Neon migration script (scripts/migrate-json-to-neon.ts)
- Prepare for user collections, decks, and authentication
- Ready for Neon database population with existing card data
2025-07-21 15:06:43 -05:00