mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-20 12:33:36 +02:00
- App display name → Cardecky in mana-apps.ts, MODULE_REGISTRY, alle Docs - Domains: cardecky.mana.how (App), cardecky-api.mana.how (Marketplace API), cardecky.com (Marketing-Landing — cloudflared-route + nginx-Block vorbereitet, DNS muss noch gesetzt werden) - 301-Redirect cards.mana.how → cardecky.mana.how (nginx + cloudflared) für alte Bookmarks; kann nach 6–12 Monaten wieder raus - SPDX license IDs Cards-Personal-Use/Pro-Only-1.0 → Cardecky-* via Drizzle 0001-Migration (DROP CHECK → UPDATE rows → SET DEFAULT → ADD CHECK), inkl. _journal- und 0001_snapshot-Update - In-mana cards-Modul: dezenter Banner zur Standalone-App (GUIDELINES §12), einmal schließbar via localStorage - Docker-CORS-Listen, sso-origins.ts, Prometheus-Target aktualisiert Technische IDs bleiben bewusst: appId 'cards', schema mana_platform.cards.*, Verzeichnis apps/cards/, Package @cards/web, services/cards-server, Env-Vars CARDS_*, UMAMI_WEBSITE_ID_CARDS*, Class CardsEvents — Mana-Konvention (Brand ≠ technischer Identifier). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
110 lines
3.8 KiB
Markdown
110 lines
3.8 KiB
Markdown
# cards-server
|
||
|
||
Cardecky Marketplace + Community backend. Owns the published-deck side
|
||
of the Cardecky product (the standalone app at `cardecky.mana.how` is
|
||
the client). Phase α is the data skeleton — schema + bootstrap + JWT
|
||
auth in place; routes land progressively in Phase β onwards.
|
||
|
||
For the full design rationale, phasing, and contract decisions see
|
||
**[`apps/cards/docs/MARKETPLACE_PLAN.md`](../../apps/cards/docs/MARKETPLACE_PLAN.md)**.
|
||
|
||
## Tech Stack
|
||
|
||
| Layer | Tech |
|
||
|-------|------|
|
||
| Runtime | Bun |
|
||
| Framework | Hono |
|
||
| Database | PostgreSQL (`mana_platform.cards.*` schema) + Drizzle ORM |
|
||
| Auth | JWT via JWKS from mana-auth (EdDSA, jose) |
|
||
| Money | mana-credits — never Stripe directly |
|
||
|
||
## Port: 3072
|
||
|
||
## Quick Start
|
||
|
||
```bash
|
||
# Schema push (writes to local mana_platform DB)
|
||
bun run db:push
|
||
|
||
# Dev server with watch
|
||
bun run dev
|
||
|
||
# Type check
|
||
bun run type-check
|
||
```
|
||
|
||
## Database
|
||
|
||
Schema: **`cards`** inside the shared `mana_platform` DB. 17 tables across
|
||
six logical groups (matching the source files in `src/db/schema/`):
|
||
|
||
| File | Tables |
|
||
|------|--------|
|
||
| `authors.ts` | `cards.authors`, `cards.author_follows` |
|
||
| `decks.ts` | `cards.decks`, `cards.deck_versions`, `cards.deck_cards` |
|
||
| `tags.ts` | `cards.tag_definitions`, `cards.deck_tags` |
|
||
| `engagement.ts` | `cards.deck_stars`, `cards.deck_subscriptions`, `cards.deck_forks` |
|
||
| `discussions.ts` | `cards.deck_pull_requests`, `cards.card_discussions` |
|
||
| `moderation.ts` | `cards.deck_reports`, `cards.ai_moderation_log` |
|
||
| `credits.ts` | `cards.deck_purchases`, `cards.author_payouts` |
|
||
|
||
`co_learn_sessions` (Phase λ) is intentionally not yet in the schema.
|
||
Every table is created via `pgSchema('cards')` per the Mana convention.
|
||
|
||
## Auth model
|
||
|
||
Three middleware:
|
||
|
||
- `jwtAuth(authUrl)` — validates Bearer tokens via JWKS. Sets
|
||
`c.set('user', { userId, email, role })`. Used on every user-facing
|
||
`/v1/*` route.
|
||
- `serviceAuth(serviceKey)` — `X-Service-Key` check for service-to-
|
||
service calls (e.g. mana-credits-webhook → cards-server).
|
||
- (planned) `optionalAuth` — for routes that should respond
|
||
differently when the caller is signed-in but never reject anonymous.
|
||
|
||
## Phasing (per MARKETPLACE_PLAN §11)
|
||
|
||
| Phase | What lands | Where |
|
||
|-------|-----------|-------|
|
||
| **α** | Skeleton + schema + JWT + health | now |
|
||
| β | Author publish flow + AI-mod-first-pass | next |
|
||
| γ | Discovery (browse, search, tags, follow) | |
|
||
| δ | Subscribe + smart-merge | |
|
||
| ε | Pull-requests + discussions | |
|
||
| ζ | mana-credits marketplace | |
|
||
| η | Moderation + trust | |
|
||
| θ | Deep AI (auto-tags, embeddings, audio) | |
|
||
| ι | Optimisation + scale | |
|
||
|
||
## Environment Variables
|
||
|
||
```env
|
||
PORT=3072
|
||
DATABASE_URL=postgresql://mana:devpassword@localhost:5432/mana_platform
|
||
MANA_AUTH_URL=http://localhost:3001
|
||
MANA_CREDITS_URL=http://localhost:3061
|
||
MANA_LLM_URL=http://localhost:3025
|
||
MANA_MEDIA_URL=http://localhost:3015
|
||
MANA_NOTIFY_URL=http://localhost:3040
|
||
MANA_SERVICE_KEY=dev-service-key
|
||
CORS_ORIGINS=http://localhost:5173,http://localhost:5180
|
||
|
||
# Author payout splits (basis points). Defaults: 80/20 standard,
|
||
# 90/10 verified-mana.
|
||
AUTHOR_PAYOUT_STANDARD_BPS=8000
|
||
AUTHOR_PAYOUT_VERIFIED_BPS=9000
|
||
|
||
# Community-verified auto-thresholds.
|
||
COMMUNITY_VERIFY_STARS=500
|
||
COMMUNITY_VERIFY_FEATURED=3
|
||
COMMUNITY_VERIFY_SUBSCRIBERS=200
|
||
```
|
||
|
||
## Critical Rules
|
||
|
||
- **Never call Stripe directly.** All money flows through mana-credits.
|
||
- **`/v1` is the public contract** — additive-only changes within v1, breaking changes go to `/v2`.
|
||
- **Content-hash everything.** Per-card and per-version SHA-256s drive smart-merge, cache invalidation, and trust.
|
||
- **Subscribed Decks are unidirectional.** Author → Subscriber. Forks for the bidirectional case.
|
||
- **Verification is binary, not numeric.** Two flags (`verified_mana`, `verified_community`), the UI shows badges. Never invent a "trust score".
|