managarten/services/cards-server
Till JS 044d948155 feat(cards-server): Phase β — author profiles + deck init/publish
First user-facing surface on cards-server. Three endpoint groups:

Authors (/v1/authors):
  - POST /me — upsert author profile (slug, displayName, bio,
    avatarUrl, pseudonym). Slug validated for length, charset, and
    against a small reserved-words list (admin, api, me, ...).
  - GET /me — read own profile (returns null if not yet an author).
  - GET /:slug — public profile (omits banned-reason, etc.)

Decks (/v1/decks):
  - POST / — claim a slug + create the metadata-only deck row.
    License defaults to Cards-Personal-Use-1.0; paid decks
    (priceCredits > 0) must use Cards-Pro-Only-1.0 (CHECK constraint
    + service-side guard).
  - GET /:slug — deck + latestVersion.
  - POST /:slug/publish — version semver enforced strictly increasing,
    AI-mod first-pass via mana-llm (block → 403; flag → publish + log
    for human review; pass → publish silently). Per-card and per-
    version SHA-256 content hashes computed; cards persisted; deck's
    latest_version_id flipped atomically in a single transaction.

Helpers:
  - lib/slug.ts — slugify (best-effort) + validateSlug (strict).
  - lib/hash.ts — canonical SHA-256 over (type, fields) for cards
    and (sorted, ord-stable) for versions.
  - lib/ai-moderation.ts — mana-llm /v1/chat/completions wrapper
    with system prompt that forces JSON output. Fail-open: if
    mana-llm is down or returns malformed JSON, the verdict is
    'flag' so a human reviewer catches it. Better slow than silent.

Index-mounting of /v1/authors and /v1/decks is gated behind jwtAuth.
Anonymous public reads (Phase γ optionalAuth middleware) come later.

Validated: tsc --noEmit clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 16:36:34 +02:00
..
drizzle feat(cards-server): Phase α — service skeleton + 16-table schema 2026-05-07 16:01:08 +02:00
src feat(cards-server): Phase β — author profiles + deck init/publish 2026-05-07 16:36:34 +02:00
.gitignore feat(cards-server): Phase α — service skeleton + 16-table schema 2026-05-07 16:01:08 +02:00
CLAUDE.md feat(cards-server): Phase α — service skeleton + 16-table schema 2026-05-07 16:01:08 +02:00
Dockerfile feat(cards-server): Phase α.4 — Dockerfile + compose + tunnel route 2026-05-07 16:22:48 +02:00
drizzle.config.ts feat(cards-server): Phase α — service skeleton + 16-table schema 2026-05-07 16:01:08 +02:00
package.json feat(cards-server): Phase α — service skeleton + 16-table schema 2026-05-07 16:01:08 +02:00
README.md feat(cards-server): Phase α — service skeleton + 16-table schema 2026-05-07 16:01:08 +02:00
tsconfig.json feat(cards-server): Phase α — service skeleton + 16-table schema 2026-05-07 16:01:08 +02:00

cards-server

Backend for the Cards marketplace. See CLAUDE.md for the technical overview and apps/cards/docs/MARKETPLACE_PLAN.md for the full product plan.