mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 17:41:09 +02:00
refactor: rename ManaDeck to Cards across entire monorepo
Rename the flashcard/deck management app from ManaDeck to Cards: - Directory: apps/manadeck → apps/cards, packages/manadeck-database → packages/cards-database - Packages: @manadeck/* → @cards/*, @manacore/manadeck-database → @manacore/cards-database - Domain: manadeck.mana.how → cards.mana.how - Storage: manadeck-storage → cards-storage - Database: manadeck → cards - All shared packages, infra configs, services, i18n, and docs updated - 244 files changed, zero remaining manadeck references Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
29b77f22e4
commit
75a3ea2957
244 changed files with 907 additions and 924 deletions
|
|
@ -87,7 +87,7 @@ Only servers that need their own database use Drizzle. Most apps rely on mana-sy
|
|||
|
||||
**Servers with Drizzle:** chat, todo, moodlit, context, planta, presi, traces, uload, wisekeep, news
|
||||
|
||||
**Servers without Drizzle (mana-sync only):** calendar, contacts, manadeck, mukke, nutriphi, picture, questions, storage
|
||||
**Servers without Drizzle (mana-sync only):** calendar, contacts, cards, mukke, nutriphi, picture, questions, storage
|
||||
|
||||
## Running Servers
|
||||
|
||||
|
|
|
|||
|
|
@ -811,7 +811,7 @@ All web apps with backends now use the runtime injection pattern:
|
|||
|
||||
### Apps That May Need Fixing
|
||||
|
||||
- ❓ `manadeck/apps/web` - Check if using dynamic URLs
|
||||
- ❓ `cards/apps/web` - Check if using dynamic URLs
|
||||
- ❓ `manacore/apps/web` - Check if using dynamic URLs
|
||||
|
||||
### Quick Checklist for New SvelteKit Apps
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
| 3 | Calendar | calendars, events | Ja (komplett) |
|
||||
| 4 | Clock | alarms, timers, worldClocks | Ja (komplett) |
|
||||
| 5 | Contacts | contacts | Ja (komplett) |
|
||||
| 6 | ManaDeck | decks, cards | Ja (komplett) |
|
||||
| 6 | Cards | decks, cards | Ja (komplett) |
|
||||
| 7 | **Presi** | decks, slides | Ja (Store + Pages umgeschrieben) |
|
||||
| 8 | **Picture** | images, boards, boardItems, tags, imageTags | Ja (Gallery + Boards umgeschrieben) |
|
||||
| 9 | **Inventar** | collections, items, locations, categories | Nein (local-store angelegt, Stores nutzen noch localStorage) |
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ Alle Web-Apps mit CRUD-Datenmodell wurden auf Local-First migriert:
|
|||
| **Zitare** | favorites, lists | Nur Sync |
|
||||
| **Calendar** | calendars, events | RRULE, Google Calendar OAuth |
|
||||
| **Clock** | alarms, timers, worldClocks | Nur Sync |
|
||||
| **ManaDeck** | decks, cards | Spaced Repetition, LLM |
|
||||
| **Cards** | decks, cards | Spaced Repetition, LLM |
|
||||
| **Contacts** | contacts | Google Import, vCard/CSV, Foto-Upload |
|
||||
| **Picture** | images, boards, boardItems, tags, imageTags | Replicate API, Upload, Explore |
|
||||
| **Presi** | decks, slides | Share-Links |
|
||||
|
|
|
|||
|
|
@ -240,5 +240,5 @@ Registrierung:
|
|||
| context | Dokumente, Wissen | context = freie Dokumente, guides = strukturierte Ausführung |
|
||||
| todo | Aufgaben, Checklisten | todo = Tasks, guides = Prozesse mit History |
|
||||
| questions | Recherche | questions = Q&A, guides = How-To |
|
||||
| manadeck | Lernen | manadeck = Karteikarten/Spaced-Repetition, guides = Schritt-für-Schritt |
|
||||
| cards | Lernen | cards = Karteikarten/Spaced-Repetition, guides = Schritt-für-Schritt |
|
||||
| skilltree | Skill-Progression | skilltree = XP-Tracking, guides = Quelle von XP (optional) |
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ manacore-monorepo/
|
|||
│ │ │ └── landing/
|
||||
│ │ └── packages/
|
||||
│ │
|
||||
│ ├── manadeck/
|
||||
│ ├── cards/
|
||||
│ │ ├── apps/
|
||||
│ │ │ ├── backend/
|
||||
│ │ │ ├── mobile/
|
||||
|
|
@ -131,7 +131,7 @@ mkdir -p services
|
|||
| ----------------- | ---------------------- |
|
||||
| `chat/` | `apps/chat/` |
|
||||
| `maerchenzauber/` | `apps/maerchenzauber/` |
|
||||
| `manadeck/` | `apps/manadeck/` |
|
||||
| `cards/` | `apps/cards/` |
|
||||
| `memoro/` | `apps/memoro/` |
|
||||
| `picture/` | `apps/picture/` |
|
||||
| `nutriphi/` | `apps/nutriphi/` |
|
||||
|
|
@ -143,7 +143,7 @@ mkdir -p services
|
|||
# Move all products to apps/
|
||||
git mv chat apps/chat
|
||||
git mv maerchenzauber apps/maerchenzauber
|
||||
git mv manadeck apps/manadeck
|
||||
git mv cards apps/cards
|
||||
git mv memoro apps/memoro
|
||||
git mv picture apps/picture
|
||||
git mv nutriphi apps/nutriphi
|
||||
|
|
@ -159,7 +159,7 @@ Projects with backends at root level need restructuring:
|
|||
| Source | Destination |
|
||||
| ------------------------ | ----------------------------- |
|
||||
| `apps/chat/backend/` | `apps/chat/apps/backend/` |
|
||||
| `apps/manadeck/backend/` | `apps/manadeck/apps/backend/` |
|
||||
| `apps/cards/backend/` | `apps/cards/apps/backend/` |
|
||||
| `apps/nutriphi/backend/` | `apps/nutriphi/apps/backend/` |
|
||||
|
||||
```bash
|
||||
|
|
@ -167,9 +167,9 @@ Projects with backends at root level need restructuring:
|
|||
mkdir -p apps/chat/apps
|
||||
git mv apps/chat/backend apps/chat/apps/backend
|
||||
|
||||
# Manadeck: move backend into apps/
|
||||
mkdir -p apps/manadeck/apps
|
||||
git mv apps/manadeck/backend apps/manadeck/apps/backend
|
||||
# Cards: move backend into apps/
|
||||
mkdir -p apps/cards/apps
|
||||
git mv apps/cards/backend apps/cards/apps/backend
|
||||
|
||||
# Nutriphi: move backend into apps/
|
||||
mkdir -p apps/nutriphi/apps
|
||||
|
|
@ -226,7 +226,7 @@ No changes needed - turbo.json uses task definitions, not paths.
|
|||
|
||||
"maerchenzauber:dev": "turbo run dev --filter=@maerchenzauber/*...",
|
||||
"manacore:dev": "turbo run dev --filter=@manacore/*...",
|
||||
"manadeck:dev": "turbo run dev --filter=@manadeck/*...",
|
||||
"cards:dev": "turbo run dev --filter=@cards/*...",
|
||||
"memoro:dev": "turbo run dev --filter=@memoro/*...",
|
||||
"picture:dev": "turbo run dev --filter=@picture/*...",
|
||||
"uload:dev": "turbo run dev --filter=@uload/*...",
|
||||
|
|
@ -244,11 +244,11 @@ No changes needed - turbo.json uses task definitions, not paths.
|
|||
"dev:manacore:landing": "pnpm --filter @manacore/landing dev",
|
||||
"dev:manacore:mobile": "pnpm --filter @manacore/mobile dev",
|
||||
|
||||
"dev:manadeck:web": "pnpm --filter @manadeck/web dev",
|
||||
"dev:manadeck:landing": "pnpm --filter @manadeck/landing dev",
|
||||
"dev:manadeck:backend": "pnpm --filter @manadeck/backend dev",
|
||||
"dev:manadeck:mobile": "pnpm --filter @manadeck/mobile dev",
|
||||
"dev:manadeck:app": "turbo run dev --filter=@manadeck/web --filter=@manadeck/backend",
|
||||
"dev:cards:web": "pnpm --filter @cards/web dev",
|
||||
"dev:cards:landing": "pnpm --filter @cards/landing dev",
|
||||
"dev:cards:backend": "pnpm --filter @cards/backend dev",
|
||||
"dev:cards:mobile": "pnpm --filter @cards/mobile dev",
|
||||
"dev:cards:app": "turbo run dev --filter=@cards/web --filter=@cards/backend",
|
||||
|
||||
"dev:memoro:web": "pnpm --filter @memoro/web dev",
|
||||
"dev:memoro:landing": "pnpm --filter @memoro/landing dev",
|
||||
|
|
|
|||
|
|
@ -135,12 +135,12 @@ UMAMI_WEBSITE_ID_PHOTOS=dc201d68-5f78-4716-a0b8-587376eca7a1
|
|||
UMAMI_WEBSITE_ID_CLOCK=f893945e-fea7-4493-82ab-f04812a54bea
|
||||
UMAMI_WEBSITE_ID_MUKKE=89015bbb-dc59-45b7-ad51-2a68a1391553
|
||||
UMAMI_WEBSITE_ID_QUESTIONS=4940b9a8-834a-483a-8696-a3086bd531e6
|
||||
UMAMI_WEBSITE_ID_MANADECK=1c1d54c4-7829-43e5-8dde-0a6db7c86ec6
|
||||
UMAMI_WEBSITE_ID_CARDS=1c1d54c4-7829-43e5-8dde-0a6db7c86ec6
|
||||
|
||||
# Landing Page Website IDs
|
||||
UMAMI_WEBSITE_ID_CHAT_LANDING=a264b165-80d2-47ab-91f4-2efc01de0b66
|
||||
UMAMI_WEBSITE_ID_MANACORE_LANDING=cef3798d-85ae-47df-a44a-e9bee09dbcf9
|
||||
UMAMI_WEBSITE_ID_MANADECK_LANDING=2ac83d50-107f-4d4e-ac23-5540946e96e3
|
||||
UMAMI_WEBSITE_ID_CARDS_LANDING=2ac83d50-107f-4d4e-ac23-5540946e96e3
|
||||
UMAMI_WEBSITE_ID_CALENDAR_LANDING=84862d98-727e-4e25-8645-639241dd1544
|
||||
UMAMI_WEBSITE_ID_CLOCK_LANDING=0332b471-a022-46af-a726-0f45932bfd58
|
||||
UMAMI_WEBSITE_ID_PICTURE_LANDING=d3ac98e6-0d1a-47a3-a218-2a81fff596bd
|
||||
|
|
@ -183,12 +183,12 @@ MAERCHENZAUBER_AZURE_OPENAI_ENDPOINT=https://your-endpoint.openai.azure.com/open
|
|||
MAERCHENZAUBER_REPLICATE_API_KEY=YOUR_KEY
|
||||
|
||||
# ============================================
|
||||
# MANADECK PROJECT
|
||||
# CARDS PROJECT
|
||||
# ============================================
|
||||
|
||||
MANADECK_BACKEND_PORT=3009
|
||||
MANADECK_DATABASE_URL=postgresql://manacore:devpassword@localhost:5432/manadeck
|
||||
MANADECK_APP_ID=cea4bfc6-a4de-4e17-91e2-54275940156e
|
||||
CARDS_BACKEND_PORT=3009
|
||||
CARDS_DATABASE_URL=postgresql://manacore:devpassword@localhost:5432/cards
|
||||
CARDS_APP_ID=cea4bfc6-a4de-4e17-91e2-54275940156e
|
||||
|
||||
# ============================================
|
||||
# PICTURE PROJECT
|
||||
|
|
|
|||
2
.github/dependabot.yml
vendored
2
.github/dependabot.yml
vendored
|
|
@ -89,7 +89,7 @@ updates:
|
|||
- "automated"
|
||||
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/apps/manadeck/apps/backend"
|
||||
directory: "/apps/cards/apps/backend"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
open-pull-requests-limit: 5
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ packages/shared-landing-ui/src/sections/TestimonialSection.astro
|
|||
**/*ANDROID*.md
|
||||
**/*IOS*.md
|
||||
apps/chat/FEATURE_REQUIREMENTS.md
|
||||
apps/manadeck/CI_CD_SETUP_GUIDE.md
|
||||
apps/manadeck/MANA_CORE_INTEGRATION_CHECKLIST.md
|
||||
apps/cards/CI_CD_SETUP_GUIDE.md
|
||||
apps/cards/MANA_CORE_INTEGRATION_CHECKLIST.md
|
||||
apps/picture/DEPLOYMENT_COMPLETE.md
|
||||
apps/zitare/apps/web/THEMING.md
|
||||
BACKEND_DESIGN_PATTERN_AUDIT.md
|
||||
|
|
|
|||
16
CLAUDE.md
16
CLAUDE.md
|
|
@ -37,7 +37,7 @@ For comprehensive guidelines on code patterns and conventions, see the `.claude/
|
|||
| **chat** | AI chat application | Backend, Mobile, Web, Landing |
|
||||
| **picture** | AI image generation | Backend, Mobile, Web, Landing |
|
||||
| **memoro** | AI voice recording & memo management | Backend, Audio-Backend, Mobile, Web, Landing |
|
||||
| **manadeck** | Card/deck management | Backend, Mobile, Web |
|
||||
| **cards** | Card/deck management | Backend, Mobile, Web |
|
||||
| **todo** | Task management | Backend, Web, Landing |
|
||||
| **calendar** | Calendar & scheduling | Backend, Web, Landing |
|
||||
| **contacts** | Contact management | Backend, Web |
|
||||
|
|
@ -117,7 +117,7 @@ pnpm setup:db:auth # Setup just auth
|
|||
# Start specific project (runs all apps in project)
|
||||
pnpm run manacore:dev
|
||||
pnpm run memoro:dev
|
||||
pnpm run manadeck:dev
|
||||
pnpm run cards:dev
|
||||
pnpm run picture:dev
|
||||
pnpm run chat:dev
|
||||
pnpm run zitare:dev
|
||||
|
|
@ -151,7 +151,7 @@ manacore-monorepo/
|
|||
│ │ │ ├── web/ # SvelteKit web app
|
||||
│ │ │ └── landing/ # Astro marketing page
|
||||
│ │ └── packages/ # Project-specific shared code
|
||||
│ ├── manadeck/
|
||||
│ ├── cards/
|
||||
│ ├── picture/
|
||||
│ └── ...
|
||||
├── apps-archived/ # Archived apps (excluded from workspace)
|
||||
|
|
@ -594,7 +594,7 @@ Logged in: App → IndexedDB → UI → SyncEngine → mana-sync (Go) → Postg
|
|||
| Calendar | calendars, events | Done |
|
||||
| Clock | alarms, timers, worldClocks | Done |
|
||||
| Contacts | contacts | Done |
|
||||
| ManaDeck | decks, cards | Done |
|
||||
| Cards | decks, cards | Done |
|
||||
| Picture | images, boards, boardItems, tags, imageTags | Done |
|
||||
| Presi | decks, slides | Done |
|
||||
| Inventar | collections, items, locations, categories | Done |
|
||||
|
|
@ -695,7 +695,7 @@ pnpm docker:up
|
|||
|--------|---------|---------|
|
||||
| `picture-storage` | Picture | AI-generated images |
|
||||
| `chat-storage` | Chat | User file uploads |
|
||||
| `manadeck-storage` | ManaDeck | Card/deck assets |
|
||||
| `cards-storage` | Cards | Card/deck assets |
|
||||
| `nutriphi-storage` | NutriPhi | Meal photos |
|
||||
| `presi-storage` | Presi | Presentation slides |
|
||||
| `calendar-storage` | Calendar | Calendar attachments |
|
||||
|
|
@ -744,7 +744,7 @@ All landing pages are deployed to Cloudflare Pages using Direct Upload via Wrang
|
|||
| Chat | `@chat/landing` | `chat-landing` | https://chat-landing.pages.dev |
|
||||
| Picture | `@picture/landing` | `picture-landing` | https://picture-landing.pages.dev |
|
||||
| ManaCore | `@manacore/landing` | `manacore-landing` | https://manacore-landing.pages.dev |
|
||||
| ManaDeck | `@manadeck/landing` | `manadeck-landing` | https://manadeck-landing.pages.dev |
|
||||
| Cards | `@cards/landing` | `cards-landing` | https://cards-landing.pages.dev |
|
||||
| Zitare | `@zitare/landing` | `zitare-landing` | https://zitare-landing.pages.dev |
|
||||
|
||||
### Local Deployment
|
||||
|
|
@ -760,7 +760,7 @@ pnpm cf:projects:create
|
|||
pnpm deploy:landing:chat
|
||||
pnpm deploy:landing:picture
|
||||
pnpm deploy:landing:manacore
|
||||
pnpm deploy:landing:manadeck
|
||||
pnpm deploy:landing:cards
|
||||
pnpm deploy:landing:zitare
|
||||
|
||||
# Deploy all landing pages
|
||||
|
|
@ -1004,7 +1004,7 @@ MANA_CORE_AUTH_URL=...
|
|||
Each project has its own `CLAUDE.md` with detailed information:
|
||||
|
||||
- `apps/manacore/CLAUDE.md` - Multi-app ecosystem, auth details
|
||||
- `apps/manadeck/CLAUDE.md` - Card/deck management
|
||||
- `apps/cards/CLAUDE.md` - Card/deck management
|
||||
- `apps/chat/CLAUDE.md` - Chat API endpoints, AI models
|
||||
- `apps/picture/CLAUDE.md` - AI image generation
|
||||
- `services/mana-core-auth/` - Central authentication service
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Monorepo containing all Manacore projects — a self-hosted multi-app ecosystem
|
|||
| **clock** | Pomodoro & time tracking | NestJS backend, SvelteKit web, Astro landing |
|
||||
| **contacts** | Contact management | NestJS backend, SvelteKit web |
|
||||
| **picture** | AI image generation | NestJS backend, Expo mobile, SvelteKit web, Astro landing |
|
||||
| **manadeck** | Card/deck management | NestJS backend, Expo mobile, SvelteKit web |
|
||||
| **cards** | Card/deck management | NestJS backend, Expo mobile, SvelteKit web |
|
||||
| **zitare** | Daily inspiration quotes | NestJS backend, Expo mobile, SvelteKit web, Astro landing |
|
||||
| **mukke** | Music player | NestJS backend, SvelteKit web |
|
||||
| **planta** | Plant care tracker | NestJS backend, SvelteKit web |
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ env:
|
|||
PROJECT_ID: mana-core-453821
|
||||
REGION: europe-west3
|
||||
ARTIFACT_REGISTRY: europe-west3-docker.pkg.dev
|
||||
SERVICE_NAME: manadeck-backend
|
||||
REPOSITORY_NAME: manadeck-backend
|
||||
SERVICE_NAME: cards-backend
|
||||
REPOSITORY_NAME: cards-backend
|
||||
WORKING_DIR: backend
|
||||
|
||||
jobs:
|
||||
|
|
@ -175,7 +175,7 @@ jobs:
|
|||
--port=8080 \
|
||||
--service-account=${{ secrets.CLOUD_RUN_SERVICE_ACCOUNT }} \
|
||||
--set-env-vars="NODE_ENV=production" \
|
||||
--set-secrets="MANA_SERVICE_URL=MANA_SERVICE_URL:latest,APP_ID=MANADECK_APP_ID:latest,MANA_SUPABASE_SECRET_KEY=MANA_SUPABASE_SECRET_KEY:latest,SUPABASE_URL=MANADECK_SUPABASE_URL:latest,SUPABASE_ANON_KEY=MANADECK_SUPABASE_ANON_KEY:latest,SUPABASE_SERVICE_KEY=MANADECK_SUPABASE_SERVICE_KEY:latest" \
|
||||
--set-secrets="MANA_SERVICE_URL=MANA_SERVICE_URL:latest,APP_ID=CARDS_APP_ID:latest,MANA_SUPABASE_SECRET_KEY=MANA_SUPABASE_SECRET_KEY:latest,SUPABASE_URL=CARDS_SUPABASE_URL:latest,SUPABASE_ANON_KEY=CARDS_SUPABASE_ANON_KEY:latest,SUPABASE_SERVICE_KEY=CARDS_SUPABASE_SERVICE_KEY:latest" \
|
||||
--labels="environment=production,commit=${{ steps.version.outputs.short_sha }},version=${{ env.version }}"
|
||||
|
||||
# Ensure 100% traffic goes to the new revision
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Complete CI/CD Setup Guide for NestJS Backend with Private Packages
|
||||
|
||||
**Last Updated**: 2025-09-30
|
||||
**Project**: Manadeck Backend
|
||||
**Project**: Cards Backend
|
||||
**Stack**: NestJS + Private GitHub Packages + Google Cloud Run
|
||||
|
||||
---
|
||||
|
|
@ -66,7 +66,7 @@ This guide documents the complete CI/CD setup for deploying a NestJS backend tha
|
|||
### Project Structure
|
||||
|
||||
```
|
||||
manadeck/
|
||||
cards/
|
||||
├── .github/
|
||||
│ └── workflows/
|
||||
│ └── deploy-backend.yml # GitHub Actions workflow
|
||||
|
|
@ -120,12 +120,12 @@ manadeck/
|
|||
|
||||
```bash
|
||||
PROJECT_ID="mana-core-453821"
|
||||
SA_NAME="manadeck-backend-sa"
|
||||
SA_NAME="cards-backend-sa"
|
||||
SA_EMAIL="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
|
||||
|
||||
# Create service account
|
||||
gcloud iam service-accounts create $SA_NAME \
|
||||
--display-name="Manadeck Backend Service Account" \
|
||||
--display-name="Cards Backend Service Account" \
|
||||
--project=$PROJECT_ID
|
||||
|
||||
# Grant required roles
|
||||
|
|
@ -151,14 +151,14 @@ gcloud projects add-iam-policy-binding $PROJECT_ID \
|
|||
#### 1.2 Create Artifact Registry Repository
|
||||
|
||||
```bash
|
||||
gcloud artifacts repositories create manadeck-backend \
|
||||
gcloud artifacts repositories create cards-backend \
|
||||
--repository-format=docker \
|
||||
--location=europe-west3 \
|
||||
--project=mana-core-453821 \
|
||||
--description="Docker images for Manadeck Backend"
|
||||
--description="Docker images for Cards Backend"
|
||||
```
|
||||
|
||||
**Common Issue**: `name unknown: Repository "manadeck-backend" not found`
|
||||
**Common Issue**: `name unknown: Repository "cards-backend" not found`
|
||||
**Solution**: Create repository before first deployment (workflow will fail without it)
|
||||
|
||||
#### 1.3 Create GCP Secrets (Same Project as Cloud Run)
|
||||
|
|
@ -182,23 +182,23 @@ PROJECT_ID="mana-core-453821"
|
|||
SERVICE_KEY=$(openssl rand -base64 32)
|
||||
|
||||
# Create secrets in the SAME project where Cloud Run will be deployed
|
||||
echo "your-app-id" | gcloud secrets create MANADECK_APP_ID \
|
||||
echo "your-app-id" | gcloud secrets create CARDS_APP_ID \
|
||||
--data-file=- \
|
||||
--project=$PROJECT_ID
|
||||
|
||||
echo "$SERVICE_KEY" | gcloud secrets create MANADECK_SERVICE_KEY \
|
||||
echo "$SERVICE_KEY" | gcloud secrets create CARDS_SERVICE_KEY \
|
||||
--data-file=- \
|
||||
--project=$PROJECT_ID
|
||||
|
||||
echo "https://xxx.supabase.co" | gcloud secrets create MANADECK_SUPABASE_URL \
|
||||
echo "https://xxx.supabase.co" | gcloud secrets create CARDS_SUPABASE_URL \
|
||||
--data-file=- \
|
||||
--project=$PROJECT_ID
|
||||
|
||||
echo "your-anon-key" | gcloud secrets create MANADECK_SUPABASE_ANON_KEY \
|
||||
echo "your-anon-key" | gcloud secrets create CARDS_SUPABASE_ANON_KEY \
|
||||
--data-file=- \
|
||||
--project=$PROJECT_ID
|
||||
|
||||
echo "your-service-role-key" | gcloud secrets create MANADECK_SUPABASE_SERVICE_KEY \
|
||||
echo "your-service-role-key" | gcloud secrets create CARDS_SUPABASE_SERVICE_KEY \
|
||||
--data-file=- \
|
||||
--project=$PROJECT_ID
|
||||
```
|
||||
|
|
@ -210,10 +210,10 @@ echo "your-service-role-key" | gcloud secrets create MANADECK_SUPABASE_SERVICE_K
|
|||
Since Cloud Run and secrets are in the **same project**, the service account automatically has access if it has the Cloud Run Admin role. However, it's best practice to explicitly grant access:
|
||||
|
||||
```bash
|
||||
SA_EMAIL="manadeck-backend-sa@mana-core-453821.iam.gserviceaccount.com"
|
||||
SA_EMAIL="cards-backend-sa@mana-core-453821.iam.gserviceaccount.com"
|
||||
PROJECT_ID="mana-core-453821"
|
||||
|
||||
for SECRET in MANA_SERVICE_URL MANADECK_APP_ID MANADECK_SERVICE_KEY MANADECK_SUPABASE_URL MANADECK_SUPABASE_ANON_KEY MANADECK_SUPABASE_SERVICE_KEY; do
|
||||
for SECRET in MANA_SERVICE_URL CARDS_APP_ID CARDS_SERVICE_KEY CARDS_SUPABASE_URL CARDS_SUPABASE_ANON_KEY CARDS_SUPABASE_SERVICE_KEY; do
|
||||
gcloud secrets add-iam-policy-binding $SECRET \
|
||||
--member="serviceAccount:${SA_EMAIL}" \
|
||||
--role="roles/secretmanager.secretAccessor" \
|
||||
|
|
@ -233,7 +233,7 @@ done
|
|||
1. Go to: https://github.com/settings/tokens
|
||||
2. Click **"Generate new token (classic)"**
|
||||
3. Settings:
|
||||
- **Name**: `Manadeck CI/CD`
|
||||
- **Name**: `Cards CI/CD`
|
||||
- **Expiration**: Choose appropriate timeframe (90 days, 1 year, or no expiration)
|
||||
- **Scopes**: ✅ `repo` (Full control of private repositories)
|
||||
4. Click **"Generate token"**
|
||||
|
|
@ -245,22 +245,22 @@ done
|
|||
#### 2.2 Generate Service Account Key
|
||||
|
||||
```bash
|
||||
gcloud iam service-accounts keys create manadeck-sa-key.json \
|
||||
--iam-account=manadeck-backend-sa@memo-2c4c4.iam.gserviceaccount.com \
|
||||
gcloud iam service-accounts keys create cards-sa-key.json \
|
||||
--iam-account=cards-backend-sa@memo-2c4c4.iam.gserviceaccount.com \
|
||||
--project=memo-2c4c4
|
||||
|
||||
# Display the JSON (copy entire output)
|
||||
cat manadeck-sa-key.json
|
||||
cat cards-sa-key.json
|
||||
|
||||
# IMPORTANT: Delete after adding to GitHub
|
||||
rm manadeck-sa-key.json
|
||||
rm cards-sa-key.json
|
||||
```
|
||||
|
||||
**Security Note**: Never commit this JSON to git. Delete local copy after adding to GitHub secrets.
|
||||
|
||||
#### 2.3 Add GitHub Repository Secrets
|
||||
|
||||
Go to: `https://github.com/Memo-2023/manadeck/settings/secrets/actions`
|
||||
Go to: `https://github.com/Memo-2023/cards/settings/secrets/actions`
|
||||
|
||||
Add these secrets:
|
||||
|
||||
|
|
@ -268,7 +268,7 @@ Add these secrets:
|
|||
|-------------|-------|-----------------|
|
||||
| `GH_PERSONAL_TOKEN` | `ghp_xxxxxxxxxxxx` | From step 2.1 |
|
||||
| `GCP_SA_KEY_PROD` | `{"type":"service_account",...}` | From step 2.2 (entire JSON) |
|
||||
| `CLOUD_RUN_SERVICE_ACCOUNT` | `manadeck-backend-sa@mana-core-453821.iam.gserviceaccount.com` | Service account email |
|
||||
| `CLOUD_RUN_SERVICE_ACCOUNT` | `cards-backend-sa@mana-core-453821.iam.gserviceaccount.com` | Service account email |
|
||||
|
||||
**Common Issue**: Forgot which secret is which
|
||||
**Solution**: Use descriptive names and document in DEPLOYMENT_CHECKLIST.md
|
||||
|
|
@ -534,8 +534,8 @@ env:
|
|||
PROJECT_ID: mana-core-453821
|
||||
REGION: europe-west3
|
||||
ARTIFACT_REGISTRY: europe-west3-docker.pkg.dev
|
||||
SERVICE_NAME: manadeck-backend
|
||||
REPOSITORY_NAME: manadeck-backend
|
||||
SERVICE_NAME: cards-backend
|
||||
REPOSITORY_NAME: cards-backend
|
||||
WORKING_DIR: backend
|
||||
|
||||
jobs:
|
||||
|
|
@ -691,7 +691,7 @@ jobs:
|
|||
--port=8080 \
|
||||
--service-account=${{ secrets.CLOUD_RUN_SERVICE_ACCOUNT }} \
|
||||
--set-env-vars="NODE_ENV=production" \
|
||||
--update-secrets="MANA_SERVICE_URL=projects/mana-core-453821/secrets/MANA_SERVICE_URL:latest,APP_ID=projects/mana-core-453821/secrets/MANADECK_APP_ID:latest,SERVICE_KEY=projects/mana-core-453821/secrets/MANADECK_SERVICE_KEY:latest,SUPABASE_URL=projects/mana-core-453821/secrets/MANADECK_SUPABASE_URL:latest,SUPABASE_ANON_KEY=projects/mana-core-453821/secrets/MANADECK_SUPABASE_ANON_KEY:latest,SUPABASE_SERVICE_KEY=projects/mana-core-453821/secrets/MANADECK_SUPABASE_SERVICE_KEY:latest,SIGNUP_REDIRECT_URL=projects/mana-core-453821/secrets/MANADECK_SIGNUP_REDIRECT_URL:latest" \
|
||||
--update-secrets="MANA_SERVICE_URL=projects/mana-core-453821/secrets/MANA_SERVICE_URL:latest,APP_ID=projects/mana-core-453821/secrets/CARDS_APP_ID:latest,SERVICE_KEY=projects/mana-core-453821/secrets/CARDS_SERVICE_KEY:latest,SUPABASE_URL=projects/mana-core-453821/secrets/CARDS_SUPABASE_URL:latest,SUPABASE_ANON_KEY=projects/mana-core-453821/secrets/CARDS_SUPABASE_ANON_KEY:latest,SUPABASE_SERVICE_KEY=projects/mana-core-453821/secrets/CARDS_SUPABASE_SERVICE_KEY:latest,SIGNUP_REDIRECT_URL=projects/mana-core-453821/secrets/CARDS_SIGNUP_REDIRECT_URL:latest" \
|
||||
--labels="environment=production,commit=${{ steps.version.outputs.short_sha }},version=${{ env.version }}"
|
||||
|
||||
# Ensure 100% traffic goes to the new revision
|
||||
|
|
@ -842,14 +842,14 @@ npm ERR! fatal: Authentication failed
|
|||
|
||||
**Error**:
|
||||
```
|
||||
name unknown: Repository "manadeck-backend" not found
|
||||
name unknown: Repository "cards-backend" not found
|
||||
```
|
||||
|
||||
**Root Cause**: Artifact Registry repository doesn't exist
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
gcloud artifacts repositories create manadeck-backend \
|
||||
gcloud artifacts repositories create cards-backend \
|
||||
--repository-format=docker \
|
||||
--location=europe-west3 \
|
||||
--project=memo-2c4c4
|
||||
|
|
@ -870,7 +870,7 @@ gcloud artifacts repositories create manadeck-backend \
|
|||
|
||||
**Solution**: Use simple format `SECRET_NAME:latest` when secrets are in same project as Cloud Run:
|
||||
```yaml
|
||||
--set-secrets="MANA_SERVICE_URL=MANA_SERVICE_URL:latest,APP_ID=MANADECK_APP_ID:latest"
|
||||
--set-secrets="MANA_SERVICE_URL=MANA_SERVICE_URL:latest,APP_ID=CARDS_APP_ID:latest"
|
||||
```
|
||||
|
||||
**Prevention**: Always keep secrets in the same project as Cloud Run deployment. Use `--set-secrets="ENV_VAR=SECRET_NAME:version"` format (not full path)
|
||||
|
|
@ -950,12 +950,12 @@ Health check failed with HTTP 503
|
|||
**Debugging**:
|
||||
```bash
|
||||
# Check service logs
|
||||
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=manadeck-backend" \
|
||||
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=cards-backend" \
|
||||
--project=memo-2c4c4 \
|
||||
--limit=50
|
||||
|
||||
# Check if secrets are accessible
|
||||
gcloud run services describe manadeck-backend \
|
||||
gcloud run services describe cards-backend \
|
||||
--project=memo-2c4c4 \
|
||||
--region=europe-west3 \
|
||||
--format=yaml
|
||||
|
|
@ -1005,13 +1005,13 @@ export GH_TOKEN="your-github-token"
|
|||
# Build with secret
|
||||
DOCKER_BUILDKIT=1 docker build \
|
||||
--secret id=github_token,env=GH_TOKEN \
|
||||
-t manadeck-backend:test \
|
||||
-t cards-backend:test \
|
||||
.
|
||||
|
||||
# Run locally
|
||||
docker run -p 8080:8080 \
|
||||
-e NODE_ENV=development \
|
||||
manadeck-backend:test
|
||||
cards-backend:test
|
||||
```
|
||||
|
||||
#### 2. Test npm ci Authentication
|
||||
|
|
@ -1040,7 +1040,7 @@ mv package-lock.json.bak package-lock.json
|
|||
|
||||
#### 1. Verify GitHub Secrets
|
||||
|
||||
Go to: `https://github.com/Memo-2023/manadeck/settings/secrets/actions`
|
||||
Go to: `https://github.com/Memo-2023/cards/settings/secrets/actions`
|
||||
|
||||
Confirm these exist:
|
||||
- ✅ `GH_PERSONAL_TOKEN`
|
||||
|
|
@ -1064,14 +1064,14 @@ gh workflow run deploy-backend.yml
|
|||
gh run watch
|
||||
|
||||
# Or view in browser
|
||||
# https://github.com/Memo-2023/manadeck/actions
|
||||
# https://github.com/Memo-2023/cards/actions
|
||||
```
|
||||
|
||||
#### 4. Check Deployment
|
||||
|
||||
```bash
|
||||
# Get service URL
|
||||
SERVICE_URL=$(gcloud run services describe manadeck-backend \
|
||||
SERVICE_URL=$(gcloud run services describe cards-backend \
|
||||
--project=memo-2c4c4 \
|
||||
--region=europe-west3 \
|
||||
--format='value(status.url)')
|
||||
|
|
@ -1083,7 +1083,7 @@ curl ${SERVICE_URL}/health
|
|||
curl ${SERVICE_URL}/health/live
|
||||
|
||||
# View logs
|
||||
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=manadeck-backend" \
|
||||
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=cards-backend" \
|
||||
--project=memo-2c4c4 \
|
||||
--limit=20
|
||||
```
|
||||
|
|
@ -1128,7 +1128,7 @@ echo "secret-value" | gcloud secrets create NEW_SECRET_NAME \
|
|||
|
||||
# 2. Grant access
|
||||
gcloud secrets add-iam-policy-binding NEW_SECRET_NAME \
|
||||
--member="serviceAccount:manadeck-backend-sa@memo-2c4c4.iam.gserviceaccount.com" \
|
||||
--member="serviceAccount:cards-backend-sa@memo-2c4c4.iam.gserviceaccount.com" \
|
||||
--role="roles/secretmanager.secretAccessor" \
|
||||
--project=mana-core-453821
|
||||
|
||||
|
|
@ -1150,7 +1150,7 @@ Adjust in workflow:
|
|||
### Monitoring
|
||||
|
||||
**Cloud Run Metrics**:
|
||||
- https://console.cloud.google.com/run/detail/europe-west3/manadeck-backend/metrics?project=memo-2c4c4
|
||||
- https://console.cloud.google.com/run/detail/europe-west3/cards-backend/metrics?project=memo-2c4c4
|
||||
|
||||
**Key Metrics**:
|
||||
- Request count
|
||||
|
|
@ -1175,7 +1175,7 @@ Adjust in workflow:
|
|||
|----------|----------|---------|
|
||||
| `NODE_ENV` | Cloud Run | Set to `production` |
|
||||
| `MANA_SERVICE_URL` | GCP Secret | Mana Core API URL |
|
||||
| `APP_ID` | GCP Secret | Manadeck app identifier |
|
||||
| `APP_ID` | GCP Secret | Cards app identifier |
|
||||
| `SERVICE_KEY` | GCP Secret | Mana Core auth key |
|
||||
| `SUPABASE_URL` | GCP Secret | Supabase project URL |
|
||||
| `SUPABASE_ANON_KEY` | GCP Secret | Supabase anonymous key |
|
||||
|
|
@ -1200,9 +1200,9 @@ Adjust in workflow:
|
|||
|
||||
### Important URLs
|
||||
|
||||
- **Repository**: https://github.com/Memo-2023/manadeck
|
||||
- **GitHub Actions**: https://github.com/Memo-2023/manadeck/actions
|
||||
- **GitHub Secrets**: https://github.com/Memo-2023/manadeck/settings/secrets/actions
|
||||
- **Repository**: https://github.com/Memo-2023/cards
|
||||
- **GitHub Actions**: https://github.com/Memo-2023/cards/actions
|
||||
- **GitHub Secrets**: https://github.com/Memo-2023/cards/settings/secrets/actions
|
||||
- **Cloud Run Console**: https://console.cloud.google.com/run?project=memo-2c4c4
|
||||
- **Artifact Registry**: https://console.cloud.google.com/artifacts?project=memo-2c4c4
|
||||
- **Secret Manager**: https://console.cloud.google.com/security/secret-manager?project=mana-core-453821
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# Manadeck Credit System
|
||||
# Cards Credit System
|
||||
|
||||
This document explains how the Mana Core credit system is integrated into Manadeck.
|
||||
This document explains how the Mana Core credit system is integrated into Cards.
|
||||
|
||||
## Overview
|
||||
|
||||
Manadeck uses **Mana** as its credit currency to charge for operations like deck creation, card generation, and AI features. The credit system is powered by [Mana Core](https://github.com/Memo-2023/mana-core-nestjs-package), which provides:
|
||||
Cards uses **Mana** as its credit currency to charge for operations like deck creation, card generation, and AI features. The credit system is powered by [Mana Core](https://github.com/Memo-2023/mana-core-nestjs-package), which provides:
|
||||
|
||||
- Credit validation before operations
|
||||
- Credit consumption after successful operations
|
||||
|
|
@ -322,7 +322,7 @@ try {
|
|||
1. **Check credit balance**:
|
||||
```bash
|
||||
curl -H "Authorization: Bearer $TOKEN" \
|
||||
https://manadeck-backend-111768794939.europe-west3.run.app/api/credits/balance
|
||||
https://cards-backend-111768794939.europe-west3.run.app/api/credits/balance
|
||||
```
|
||||
|
||||
2. **Create deck with sufficient credits**:
|
||||
|
|
@ -331,7 +331,7 @@ try {
|
|||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"Test Deck","description":"Testing"}' \
|
||||
https://manadeck-backend-111768794939.europe-west3.run.app/api/decks
|
||||
https://cards-backend-111768794939.europe-west3.run.app/api/decks
|
||||
```
|
||||
|
||||
3. **Create deck with insufficient credits**:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Manadeck Backend Deployment Checklist
|
||||
# Cards Backend Deployment Checklist
|
||||
|
||||
This checklist ensures you have everything configured for automated deployment.
|
||||
|
||||
|
|
@ -6,26 +6,26 @@ This checklist ensures you have everything configured for automated deployment.
|
|||
|
||||
### 1. GitHub Secrets (Required)
|
||||
|
||||
Go to `https://github.com/Memo-2023/manadeck` → Settings → Secrets and variables → Actions
|
||||
Go to `https://github.com/Memo-2023/cards` → Settings → Secrets and variables → Actions
|
||||
|
||||
Add these secrets:
|
||||
|
||||
| Secret Name | Description | How to Get |
|
||||
| --------------------------- | ------------------------------------------------- | -------------------------------------------------------- |
|
||||
| `GCP_SA_KEY_PROD` | Service account JSON key for Cloud Run deployment | See "Create Service Account" below |
|
||||
| `CLOUD_RUN_SERVICE_ACCOUNT` | Service account email | `manadeck-backend-sa@memo-2c4c4.iam.gserviceaccount.com` |
|
||||
| `GH_PERSONAL_TOKEN` | GitHub Personal Access Token for private packages | See "Create GitHub PAT" below |
|
||||
| Secret Name | Description | How to Get |
|
||||
| --------------------------- | ------------------------------------------------- | ----------------------------------------------------- |
|
||||
| `GCP_SA_KEY_PROD` | Service account JSON key for Cloud Run deployment | See "Create Service Account" below |
|
||||
| `CLOUD_RUN_SERVICE_ACCOUNT` | Service account email | `cards-backend-sa@memo-2c4c4.iam.gserviceaccount.com` |
|
||||
| `GH_PERSONAL_TOKEN` | GitHub Personal Access Token for private packages | See "Create GitHub PAT" below |
|
||||
|
||||
#### Create Service Account
|
||||
|
||||
```bash
|
||||
# 1. Create service account
|
||||
gcloud iam service-accounts create manadeck-backend-sa \
|
||||
--display-name="Manadeck Backend Service Account" \
|
||||
gcloud iam service-accounts create cards-backend-sa \
|
||||
--display-name="Cards Backend Service Account" \
|
||||
--project=memo-2c4c4
|
||||
|
||||
# 2. Grant permissions
|
||||
SA_EMAIL="manadeck-backend-sa@memo-2c4c4.iam.gserviceaccount.com"
|
||||
SA_EMAIL="cards-backend-sa@memo-2c4c4.iam.gserviceaccount.com"
|
||||
|
||||
gcloud projects add-iam-policy-binding memo-2c4c4 \
|
||||
--member="serviceAccount:${SA_EMAIL}" \
|
||||
|
|
@ -40,22 +40,22 @@ gcloud projects add-iam-policy-binding memo-2c4c4 \
|
|||
--role="roles/artifactregistry.writer"
|
||||
|
||||
# 3. Create and download key
|
||||
gcloud iam service-accounts keys create manadeck-sa-key.json \
|
||||
gcloud iam service-accounts keys create cards-sa-key.json \
|
||||
--iam-account=${SA_EMAIL} \
|
||||
--project=memo-2c4c4
|
||||
|
||||
# 4. Copy contents of manadeck-sa-key.json to GCP_SA_KEY_PROD secret
|
||||
cat manadeck-sa-key.json
|
||||
# 4. Copy contents of cards-sa-key.json to GCP_SA_KEY_PROD secret
|
||||
cat cards-sa-key.json
|
||||
|
||||
# 5. Delete local key file (security best practice)
|
||||
rm manadeck-sa-key.json
|
||||
rm cards-sa-key.json
|
||||
```
|
||||
|
||||
#### Create GitHub Personal Access Token
|
||||
|
||||
1. Go to https://github.com/settings/tokens
|
||||
2. Click "Generate new token (classic)"
|
||||
3. Name: `Manadeck CI/CD`
|
||||
3. Name: `Cards CI/CD`
|
||||
4. Expiration: Choose appropriate timeframe
|
||||
5. Scopes: Select `repo` (Full control of private repositories)
|
||||
6. Click "Generate token"
|
||||
|
|
@ -65,11 +65,11 @@ rm manadeck-sa-key.json
|
|||
|
||||
```bash
|
||||
# Create repository for Docker images
|
||||
gcloud artifacts repositories create manadeck-backend \
|
||||
gcloud artifacts repositories create cards-backend \
|
||||
--repository-format=docker \
|
||||
--location=europe-west3 \
|
||||
--project=memo-2c4c4 \
|
||||
--description="Docker images for Manadeck Backend"
|
||||
--description="Docker images for Cards Backend"
|
||||
```
|
||||
|
||||
### 3. GCP Secrets (Required)
|
||||
|
|
@ -91,17 +91,17 @@ PROJECT_ID="mana-core-453821"
|
|||
SERVICE_KEY=$(openssl rand -base64 32)
|
||||
|
||||
# Create secrets
|
||||
echo "your-app-id" | gcloud secrets create MANADECK_APP_ID --data-file=- --project=$PROJECT_ID
|
||||
echo "$SERVICE_KEY" | gcloud secrets create MANADECK_SERVICE_KEY --data-file=- --project=$PROJECT_ID
|
||||
echo "https://xxx.supabase.co" | gcloud secrets create MANADECK_SUPABASE_URL --data-file=- --project=$PROJECT_ID
|
||||
echo "your-anon-key" | gcloud secrets create MANADECK_SUPABASE_ANON_KEY --data-file=- --project=$PROJECT_ID
|
||||
echo "your-service-key" | gcloud secrets create MANADECK_SUPABASE_SERVICE_KEY --data-file=- --project=$PROJECT_ID
|
||||
echo "https://app.com/welcome" | gcloud secrets create MANADECK_SIGNUP_REDIRECT_URL --data-file=- --project=$PROJECT_ID
|
||||
echo "your-app-id" | gcloud secrets create CARDS_APP_ID --data-file=- --project=$PROJECT_ID
|
||||
echo "$SERVICE_KEY" | gcloud secrets create CARDS_SERVICE_KEY --data-file=- --project=$PROJECT_ID
|
||||
echo "https://xxx.supabase.co" | gcloud secrets create CARDS_SUPABASE_URL --data-file=- --project=$PROJECT_ID
|
||||
echo "your-anon-key" | gcloud secrets create CARDS_SUPABASE_ANON_KEY --data-file=- --project=$PROJECT_ID
|
||||
echo "your-service-key" | gcloud secrets create CARDS_SUPABASE_SERVICE_KEY --data-file=- --project=$PROJECT_ID
|
||||
echo "https://app.com/welcome" | gcloud secrets create CARDS_SIGNUP_REDIRECT_URL --data-file=- --project=$PROJECT_ID
|
||||
|
||||
# Grant access to service account
|
||||
SA_EMAIL="manadeck-backend-sa@memo-2c4c4.iam.gserviceaccount.com"
|
||||
SA_EMAIL="cards-backend-sa@memo-2c4c4.iam.gserviceaccount.com"
|
||||
|
||||
for SECRET in MANA_SERVICE_URL MANADECK_APP_ID MANADECK_SERVICE_KEY MANADECK_SUPABASE_URL MANADECK_SUPABASE_ANON_KEY MANADECK_SUPABASE_SERVICE_KEY MANADECK_SIGNUP_REDIRECT_URL; do
|
||||
for SECRET in MANA_SERVICE_URL CARDS_APP_ID CARDS_SERVICE_KEY CARDS_SUPABASE_URL CARDS_SUPABASE_ANON_KEY CARDS_SUPABASE_SERVICE_KEY CARDS_SIGNUP_REDIRECT_URL; do
|
||||
gcloud secrets add-iam-policy-binding $SECRET \
|
||||
--member="serviceAccount:${SA_EMAIL}" \
|
||||
--role="roles/secretmanager.secretAccessor" \
|
||||
|
|
@ -136,7 +136,7 @@ APP_SERVICE_KEYS=existing-apps,YOUR_APP_ID:YOUR_SERVICE_KEY
|
|||
- ✅ Rollback on failure
|
||||
|
||||
3. Monitor deployment:
|
||||
- Go to https://github.com/Memo-2023/manadeck/actions
|
||||
- Go to https://github.com/Memo-2023/cards/actions
|
||||
- View workflow run progress
|
||||
|
||||
### Manual Deployment (Cloud Build)
|
||||
|
|
@ -150,8 +150,8 @@ cd backend
|
|||
gcloud builds submit --project=memo-2c4c4 --config=cloudbuild.yaml .
|
||||
|
||||
# Deploy
|
||||
gcloud run deploy manadeck-backend \
|
||||
--image=europe-west3-docker.pkg.dev/memo-2c4c4/manadeck-backend/manadeck-backend:v1.0.1 \
|
||||
gcloud run deploy cards-backend \
|
||||
--image=europe-west3-docker.pkg.dev/memo-2c4c4/cards-backend/cards-backend:v1.0.1 \
|
||||
--project=memo-2c4c4 \
|
||||
--region=europe-west3
|
||||
```
|
||||
|
|
@ -162,28 +162,28 @@ gcloud run deploy manadeck-backend \
|
|||
|
||||
```bash
|
||||
# Get service URL
|
||||
gcloud run services describe manadeck-backend \
|
||||
gcloud run services describe cards-backend \
|
||||
--project=memo-2c4c4 \
|
||||
--region=europe-west3 \
|
||||
--format='value(status.url)'
|
||||
|
||||
# Test health endpoint
|
||||
curl https://manadeck-backend-xxx.run.app/health
|
||||
curl https://cards-backend-xxx.run.app/health
|
||||
|
||||
# Test liveness
|
||||
curl https://manadeck-backend-xxx.run.app/health/live
|
||||
curl https://cards-backend-xxx.run.app/health/live
|
||||
```
|
||||
|
||||
### View Logs
|
||||
|
||||
```bash
|
||||
# Recent logs
|
||||
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=manadeck-backend" \
|
||||
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=cards-backend" \
|
||||
--project=memo-2c4c4 \
|
||||
--limit=50
|
||||
|
||||
# Error logs only
|
||||
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=manadeck-backend AND severity>=ERROR" \
|
||||
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=cards-backend AND severity>=ERROR" \
|
||||
--project=memo-2c4c4 \
|
||||
--limit=20
|
||||
```
|
||||
|
|
@ -203,9 +203,9 @@ gcloud logging read "resource.type=cloud_run_revision AND resource.labels.servic
|
|||
**Solution**: Grant cross-project secret access:
|
||||
|
||||
```bash
|
||||
SA_EMAIL="manadeck-backend-sa@memo-2c4c4.iam.gserviceaccount.com"
|
||||
SA_EMAIL="cards-backend-sa@memo-2c4c4.iam.gserviceaccount.com"
|
||||
|
||||
gcloud secrets add-iam-policy-binding MANADECK_APP_ID \
|
||||
gcloud secrets add-iam-policy-binding CARDS_APP_ID \
|
||||
--member="serviceAccount:${SA_EMAIL}" \
|
||||
--role="roles/secretmanager.secretAccessor" \
|
||||
--project=mana-core-453821
|
||||
|
|
@ -225,12 +225,12 @@ gcloud secrets add-iam-policy-binding MANADECK_APP_ID \
|
|||
|
||||
```bash
|
||||
# Check service logs
|
||||
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=manadeck-backend" \
|
||||
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=cards-backend" \
|
||||
--project=memo-2c4c4 \
|
||||
--limit=20
|
||||
|
||||
# Check secret values (if you have permissions)
|
||||
gcloud secrets versions access latest --secret=MANADECK_APP_ID --project=mana-core-453821
|
||||
gcloud secrets versions access latest --secret=CARDS_APP_ID --project=mana-core-453821
|
||||
```
|
||||
|
||||
### Peer Dependency Warning
|
||||
|
|
@ -246,7 +246,7 @@ npm install --legacy-peer-deps
|
|||
## 📊 Project Structure
|
||||
|
||||
```
|
||||
manadeck/
|
||||
cards/
|
||||
├── .github/
|
||||
│ └── workflows/
|
||||
│ └── deploy-backend.yml # GitHub Actions workflow
|
||||
|
|
@ -267,15 +267,15 @@ manadeck/
|
|||
|
||||
## 📝 Configuration Summary
|
||||
|
||||
| Component | Location | Value |
|
||||
| ---------------------- | ----------------- | --------------------------------------------------------- |
|
||||
| **Deployment Project** | GCP | `memo-2c4c4` |
|
||||
| **Secrets Project** | GCP | `mana-core-453821` |
|
||||
| **Region** | GCP | `europe-west3` |
|
||||
| **Service Name** | Cloud Run | `manadeck-backend` |
|
||||
| **Image Registry** | Artifact Registry | `europe-west3-docker.pkg.dev/memo-2c4c4/manadeck-backend` |
|
||||
| **Port** | Container | `8080` |
|
||||
| **Repository** | GitHub | `Memo-2023/manadeck` |
|
||||
| Component | Location | Value |
|
||||
| ---------------------- | ----------------- | ------------------------------------------------------ |
|
||||
| **Deployment Project** | GCP | `memo-2c4c4` |
|
||||
| **Secrets Project** | GCP | `mana-core-453821` |
|
||||
| **Region** | GCP | `europe-west3` |
|
||||
| **Service Name** | Cloud Run | `cards-backend` |
|
||||
| **Image Registry** | Artifact Registry | `europe-west3-docker.pkg.dev/memo-2c4c4/cards-backend` |
|
||||
| **Port** | Container | `8080` |
|
||||
| **Repository** | GitHub | `Memo-2023/cards` |
|
||||
|
||||
## 🎯 Quick Start
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ Deno.serve(async (req) => {
|
|||
|
||||
## Critical: Disable Gateway JWT Verification
|
||||
|
||||
The Supabase Edge Gateway tries to validate JWTs before passing requests to your function. Since you're using Mana Core JWTs (not Manadeck JWTs), you need to disable this.
|
||||
The Supabase Edge Gateway tries to validate JWTs before passing requests to your function. Since you're using Mana Core JWTs (not Cards JWTs), you need to disable this.
|
||||
|
||||
Create `supabase/functions/generate-deck/config.toml`:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Manadeck
|
||||
# Cards
|
||||
|
||||
A deck management system with Mana Core authentication and credit system integration.
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ A deck management system with Mana Core authentication and credit system integra
|
|||
|
||||
## Credit System
|
||||
|
||||
Manadeck uses **Mana** as its credit currency. Operations cost credits:
|
||||
Cards uses **Mana** as its credit currency. Operations cost credits:
|
||||
|
||||
| Operation | Cost |
|
||||
|-----------|------|
|
||||
|
|
@ -208,7 +208,7 @@ function MyScreen() {
|
|||
## Project Structure
|
||||
|
||||
```
|
||||
manadeck/
|
||||
cards/
|
||||
├── backend/ # NestJS backend
|
||||
│ ├── src/
|
||||
│ │ ├── config/
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Manadeck Setup Guide
|
||||
# Cards Setup Guide
|
||||
|
||||
## What's Been Completed
|
||||
|
||||
|
|
@ -59,12 +59,12 @@ npm run start:dev
|
|||
# Sign up a test user
|
||||
curl -X POST http://localhost:8080/v1/auth/signup \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"test@manadeck.com","password":"test123","username":"testuser"}'
|
||||
-d '{"email":"test@cards.com","password":"test123","username":"testuser"}'
|
||||
|
||||
# Sign in to get token
|
||||
curl -X POST http://localhost:8080/v1/auth/signin \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"test@manadeck.com","password":"test123"}'
|
||||
-d '{"email":"test@cards.com","password":"test123"}'
|
||||
|
||||
# Copy the appToken from response
|
||||
export TOKEN="paste-your-token-here"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sitemap from '@astrojs/sitemap';
|
|||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
site: 'https://manadeck.app',
|
||||
site: 'https://cards.app',
|
||||
integrations: [tailwind(), sitemap()],
|
||||
vite: {
|
||||
ssr: {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@manadeck/landing",
|
||||
"name": "@cards/landing",
|
||||
"version": "0.2.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://manadeck.app/sitemap-index.xml
|
||||
Sitemap: https://cards.app/sitemap-index.xml
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const currentYear = new Date().getFullYear();
|
|||
<div class="col-span-1 md:col-span-2">
|
||||
<a href="/" class="flex items-center gap-2 mb-4">
|
||||
<span class="text-2xl">🃏</span>
|
||||
<span class="font-bold text-xl text-text-primary">ManaDeck</span>
|
||||
<span class="font-bold text-xl text-text-primary">Cards</span>
|
||||
</a>
|
||||
<p class="text-text-secondary text-sm max-w-md">
|
||||
Dein KI-gestützter Lernpartner. Erstelle intelligente Karteikarten aus deinen Notizen und
|
||||
|
|
@ -75,7 +75,7 @@ const currentYear = new Date().getFullYear();
|
|||
class="mt-12 pt-8 border-t border-border flex flex-col sm:flex-row justify-between items-center gap-4"
|
||||
>
|
||||
<p class="text-text-muted text-sm">
|
||||
© {currentYear} ManaDeck. Alle Rechte vorbehalten.
|
||||
© {currentYear} Cards. Alle Rechte vorbehalten.
|
||||
</p>
|
||||
<p class="text-text-muted text-sm">Made with 💜 in Germany</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const navLinks = [
|
|||
<!-- Logo -->
|
||||
<a href="/" class="flex items-center gap-2">
|
||||
<span class="text-2xl">🃏</span>
|
||||
<span class="font-bold text-xl text-text-primary">ManaDeck</span>
|
||||
<span class="font-bold text-xl text-text-primary">Cards</span>
|
||||
</a>
|
||||
|
||||
<!-- Desktop Navigation -->
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ interface Props {
|
|||
|
||||
const {
|
||||
title,
|
||||
description = 'ManaDeck - Dein KI-gestützter Lernpartner für Karteikarten und effektives Lernen',
|
||||
description = 'Cards - Dein KI-gestützter Lernpartner für Karteikarten und effektives Lernen',
|
||||
} = Astro.props;
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import Layout from '../layouts/Layout.astro';
|
|||
import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTemplate.astro';
|
||||
---
|
||||
|
||||
<Layout title="Cookie-Richtlinie - ManaDeck">
|
||||
<Layout title="Cookie-Richtlinie - Cards">
|
||||
<LegalPageTemplate
|
||||
title="Cookie-Richtlinie"
|
||||
backLink="/"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import Layout from '../layouts/Layout.astro';
|
|||
import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTemplate.astro';
|
||||
---
|
||||
|
||||
<Layout title="Impressum - ManaDeck">
|
||||
<Layout title="Impressum - Cards">
|
||||
<LegalPageTemplate
|
||||
title="Impressum"
|
||||
backLink="/"
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ const steps = [
|
|||
number: '1',
|
||||
title: 'Inhalte hochladen',
|
||||
description:
|
||||
'Lade deine Notizen, PDFs oder Texte hoch. ManaDeck unterstützt verschiedene Formate.',
|
||||
'Lade deine Notizen, PDFs oder Texte hoch. Cards unterstützt verschiedene Formate.',
|
||||
image: '/screenshots/upload.png',
|
||||
},
|
||||
{
|
||||
|
|
@ -140,7 +140,7 @@ const faqs = [
|
|||
{
|
||||
question: 'Wie funktioniert die KI-Karteikarten-Generierung?',
|
||||
answer:
|
||||
'ManaDeck verwendet fortschrittliche KI-Modelle, um deine Texte zu analysieren und die wichtigsten Konzepte zu extrahieren. Daraus werden automatisch Frage-Antwort-Paare erstellt, die du als Karteikarten lernen kannst.',
|
||||
'Cards verwendet fortschrittliche KI-Modelle, um deine Texte zu analysieren und die wichtigsten Konzepte zu extrahieren. Daraus werden automatisch Frage-Antwort-Paare erstellt, die du als Karteikarten lernen kannst.',
|
||||
},
|
||||
{
|
||||
question: 'Was ist Spaced Repetition?',
|
||||
|
|
@ -155,7 +155,7 @@ const faqs = [
|
|||
{
|
||||
question: 'Welche Dateiformate werden unterstützt?',
|
||||
answer:
|
||||
'ManaDeck unterstützt PDF, Word-Dokumente (.docx), Textdateien (.txt) und Markdown (.md). Du kannst auch direkt Text in die App einfügen.',
|
||||
'Cards unterstützt PDF, Word-Dokumente (.docx), Textdateien (.txt) und Markdown (.md). Du kannst auch direkt Text in die App einfügen.',
|
||||
},
|
||||
{
|
||||
question: 'Sind meine Daten sicher?',
|
||||
|
|
@ -170,13 +170,13 @@ const faqs = [
|
|||
];
|
||||
---
|
||||
|
||||
<Layout title="ManaDeck - KI-gestützte Karteikarten für effektives Lernen">
|
||||
<Layout title="Cards - KI-gestützte Karteikarten für effektives Lernen">
|
||||
<Navigation />
|
||||
|
||||
<main class="pt-16">
|
||||
<HeroSection
|
||||
title="Lerne smarter, nicht härter"
|
||||
subtitle="ManaDeck verwandelt deine Notizen in intelligente Karteikarten. Mit KI-Generierung und Spaced Repetition lernst du effizienter als je zuvor."
|
||||
subtitle="Cards verwandelt deine Notizen in intelligente Karteikarten. Mit KI-Generierung und Spaced Repetition lernst du effizienter als je zuvor."
|
||||
variant="default"
|
||||
primaryCta={{
|
||||
text: 'Jetzt kostenlos starten',
|
||||
|
|
@ -197,7 +197,7 @@ const faqs = [
|
|||
<FeatureSection
|
||||
id="features"
|
||||
title="Alles was du zum Lernen brauchst"
|
||||
subtitle="ManaDeck kombiniert KI-Technologie mit bewährten Lernmethoden für maximalen Lernerfolg."
|
||||
subtitle="Cards kombiniert KI-Technologie mit bewährten Lernmethoden für maximalen Lernerfolg."
|
||||
features={features}
|
||||
columns={3}
|
||||
variant="cards"
|
||||
|
|
@ -257,14 +257,14 @@ const faqs = [
|
|||
<FAQSection
|
||||
id="faq"
|
||||
title="Häufig gestellte Fragen"
|
||||
subtitle="Alles was du über ManaDeck wissen musst"
|
||||
subtitle="Alles was du über Cards wissen musst"
|
||||
faqs={faqs}
|
||||
/>
|
||||
|
||||
<CTASection
|
||||
id="download"
|
||||
title="Bereit, smarter zu lernen?"
|
||||
subtitle="Lade ManaDeck jetzt herunter und erstelle deine ersten KI-generierten Karteikarten. Kostenlos und ohne Kreditkarte."
|
||||
subtitle="Lade Cards jetzt herunter und erstelle deine ersten KI-generierten Karteikarten. Kostenlos und ohne Kreditkarte."
|
||||
primaryCta={{ text: 'App herunterladen', href: '#' }}
|
||||
variant="highlighted"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import ManaPricingSection from '@manacore/shared-landing-ui/sections/ManaPricing
|
|||
---
|
||||
|
||||
<Layout
|
||||
title="Preise - ManaDeck"
|
||||
description="Transparente Preise für ManaDeck - Wähle den passenden Mana-Plan für deine Karteikarten und Lerndecks."
|
||||
title="Preise - Cards"
|
||||
description="Transparente Preise für Cards - Wähle den passenden Mana-Plan für deine Karteikarten und Lerndecks."
|
||||
>
|
||||
<Navigation />
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import Layout from '../layouts/Layout.astro';
|
|||
import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTemplate.astro';
|
||||
---
|
||||
|
||||
<Layout title="Datenschutzerklärung - ManaDeck">
|
||||
<Layout title="Datenschutzerklärung - Cards">
|
||||
<LegalPageTemplate
|
||||
title="Datenschutzerklärung"
|
||||
backLink="/"
|
||||
|
|
@ -13,7 +13,7 @@ import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTe
|
|||
<h2>1. Einleitung</h2>
|
||||
<p>
|
||||
Diese Datenschutzerklärung informiert Sie über die Art, den Umfang und den Zweck der
|
||||
Verarbeitung personenbezogener Daten innerhalb unserer ManaDeck-Anwendung.
|
||||
Verarbeitung personenbezogener Daten innerhalb unserer Cards-Anwendung.
|
||||
</p>
|
||||
|
||||
<h2>2. Verantwortlicher</h2>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import Layout from '../layouts/Layout.astro';
|
|||
import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTemplate.astro';
|
||||
---
|
||||
|
||||
<Layout title="Nutzungsbedingungen - ManaDeck">
|
||||
<Layout title="Nutzungsbedingungen - Cards">
|
||||
<LegalPageTemplate
|
||||
title="Nutzungsbedingungen"
|
||||
backLink="/"
|
||||
|
|
@ -12,12 +12,12 @@ import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTe
|
|||
>
|
||||
<h2>1. Geltungsbereich</h2>
|
||||
<p>
|
||||
Diese Nutzungsbedingungen gelten für die Nutzung der ManaDeck-Anwendung, einschließlich der
|
||||
Diese Nutzungsbedingungen gelten für die Nutzung der Cards-Anwendung, einschließlich der
|
||||
mobilen Apps und der Web-Version.
|
||||
</p>
|
||||
|
||||
<h2>2. Leistungsbeschreibung</h2>
|
||||
<p>ManaDeck bietet:</p>
|
||||
<p>Cards bietet:</p>
|
||||
<ul>
|
||||
<li>KI-gestützte Erstellung von Karteikarten</li>
|
||||
<li>Spaced-Repetition-Lernsystem</li>
|
||||
|
|
@ -32,7 +32,7 @@ import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTe
|
|||
</p>
|
||||
|
||||
<h2>4. Kostenfreie und kostenpflichtige Funktionen</h2>
|
||||
<p>ManaDeck bietet sowohl kostenfreie als auch Premium-Funktionen:</p>
|
||||
<p>Cards bietet sowohl kostenfreie als auch Premium-Funktionen:</p>
|
||||
<ul>
|
||||
<li><strong>Free:</strong> Grundfunktionen mit begrenzten Karten</li>
|
||||
<li><strong>Pro:</strong> Unbegrenzte Karten und erweiterte KI-Funktionen</li>
|
||||
|
|
@ -49,8 +49,8 @@ import LegalPageTemplate from '@manacore/shared-landing-ui/templates/LegalPageTe
|
|||
|
||||
<h2>6. Geistiges Eigentum</h2>
|
||||
<p>
|
||||
Die von Ihnen erstellten oder generierten Karteikarten gehören Ihnen. ManaDeck behält die
|
||||
Rechte an der Software und dem Design.
|
||||
Die von Ihnen erstellten oder generierten Karteikarten gehören Ihnen. Cards behält die Rechte
|
||||
an der Software und dem Design.
|
||||
</p>
|
||||
|
||||
<h2>7. Verfügbarkeit</h2>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/* ManaDeck Theme CSS Variables */
|
||||
/* Cards Theme CSS Variables */
|
||||
:root {
|
||||
/* Primary colors - ManaDeck Purple */
|
||||
/* Primary colors - Cards Purple */
|
||||
--color-primary: #7C3AED;
|
||||
--color-primary-hover: #8B5CF6;
|
||||
--color-primary-glow: rgba(124, 58, 237, 0.3);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export default {
|
|||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
// ManaDeck Purple Theme
|
||||
// Cards Purple Theme
|
||||
primary: {
|
||||
DEFAULT: '#7C3AED',
|
||||
hover: '#8B5CF6',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Cloudflare Pages configuration for ManaDeck Landing
|
||||
# Cloudflare Pages configuration for Cards Landing
|
||||
# Deployed via GitHub Actions (Direct Upload)
|
||||
|
||||
name = "manadeck-landing"
|
||||
name = "cards-landing"
|
||||
compatibility_date = "2024-12-01"
|
||||
pages_build_output_dir = "dist"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# ManaDeck Mobile App Environment Variables
|
||||
# Cards Mobile App Environment Variables
|
||||
|
||||
# Backend API URL
|
||||
EXPO_PUBLIC_BACKEND_URL=http://localhost:3000
|
||||
|
||||
# Mana Core Auth
|
||||
EXPO_PUBLIC_MANA_MIDDLEWARE_URL=https://api.manacore.de
|
||||
EXPO_PUBLIC_MIDDLEWARE_APP_ID=manadeck
|
||||
EXPO_PUBLIC_MIDDLEWARE_APP_ID=cards
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ EXPO_PUBLIC_SUPABASE_URL=https://vksoodohrbjwyloitvsz.supabase.co
|
|||
EXPO_PUBLIC_SUPABASE_ANON_KEY=sb_publishable_2ndX-kBHFpbDlL_ZeeOnfQ_ZlLI8ONk
|
||||
|
||||
# Backend API Configuration - Production
|
||||
EXPO_PUBLIC_API_URL=https://manadeck-backend-111768794939.europe-west3.run.app
|
||||
EXPO_PUBLIC_API_URL=https://cards-backend-111768794939.europe-west3.run.app
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||
|
||||
## Project Overview
|
||||
|
||||
Manadeck is a React Native/Expo application using Expo Router for navigation, TypeScript for type safety, NativeWind (Tailwind CSS) for styling, and Mana Core Auth for authentication. The app uses Zustand for state management and connects to the NestJS backend (port 3009).
|
||||
Cards is a React Native/Expo application using Expo Router for navigation, TypeScript for type safety, NativeWind (Tailwind CSS) for styling, and Mana Core Auth for authentication. The app uses Zustand for state management and connects to the NestJS backend (port 3009).
|
||||
|
||||
## Essential Commands
|
||||
|
||||
|
|
@ -133,6 +133,6 @@ Project configured with EAS Build:
|
|||
|
||||
### Platform-Specific Setup
|
||||
|
||||
- iOS: Bundle ID `com.tilljs.manadeck`
|
||||
- Android: Package `com.tilljs.manadeck`
|
||||
- iOS: Bundle ID `com.tilljs.cards`
|
||||
- Android: Package `com.tilljs.cards`
|
||||
- Uses Expo development build for custom native code
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Vision API für Kartenerstellung
|
|||
☐ AI Features Planning: Technische
|
||||
Architektur und API Integration
|
||||
|
||||
⏺ 🤖 AI Features Implementation Plan - Manadeck
|
||||
⏺ 🤖 AI Features Implementation Plan - Cards
|
||||
|
||||
Übersicht der AI-Features
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# Native Tab Behavior - Manadeck App
|
||||
# Native Tab Behavior - Cards App
|
||||
|
||||
## Übersicht
|
||||
|
||||
Die Manadeck-App nutzt die **Native Tabs** von Expo Router (SDK 54+), um eine native iOS/Android Tab-Navigation zu implementieren. Diese Dokumentation beschreibt die Konfiguration und das Verhalten der Tabs in unserer App.
|
||||
Die Cards-App nutzt die **Native Tabs** von Expo Router (SDK 54+), um eine native iOS/Android Tab-Navigation zu implementieren. Diese Dokumentation beschreibt die Konfiguration und das Verhalten der Tabs in unserer App.
|
||||
|
||||
## Aktuelle Implementierung
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ Wir verwenden `minimizeBehavior="automatic"`, weil:
|
|||
2. **Tab-Leisten-Höhe nicht messbar** - Position variiert je nach Gerät (iPad, Vision Pro, etc.)
|
||||
3. **Keine verschachtelten Native Tabs** - JavaScript Tabs können aber innerhalb von Native Tabs verschachtelt werden
|
||||
|
||||
## Best Practices für Manadeck
|
||||
## Best Practices für Cards
|
||||
|
||||
### Icons
|
||||
|
||||
|
|
@ -154,4 +154,4 @@ npm run android
|
|||
|
||||
**Status:** ✅ Experimentell (API kann sich ändern)
|
||||
**Plattform:** iOS (primär), Android (geplant)
|
||||
**Maintainer:** Manadeck Team
|
||||
**Maintainer:** Cards Team
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# Manadeck Datenbank-Dokumentation
|
||||
# Cards Datenbank-Dokumentation
|
||||
|
||||
## Übersicht
|
||||
|
||||
Die Manadeck-Anwendung verwendet **Supabase** (PostgreSQL) als Backend-Datenbank. Die Datenbank ist für eine mobile Lern- und Karteikarten-Anwendung konzipiert und unterstützt Multi-User-Funktionalität mit Row Level Security (RLS).
|
||||
Die Cards-Anwendung verwendet **Supabase** (PostgreSQL) als Backend-Datenbank. Die Datenbank ist für eine mobile Lern- und Karteikarten-Anwendung konzipiert und unterstützt Multi-User-Funktionalität mit Row Level Security (RLS).
|
||||
|
||||
## Datenbankstruktur
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# Expo SDK 54 Upgrade Guide für Manadeck
|
||||
# Expo SDK 54 Upgrade Guide für Cards
|
||||
|
||||
## 🎯 Übersicht
|
||||
|
||||
Dieses Dokument beschreibt die notwendigen Schritte für das Upgrade von Manadeck von Expo SDK 53 auf SDK 54.
|
||||
Dieses Dokument beschreibt die notwendigen Schritte für das Upgrade von Cards von Expo SDK 53 auf SDK 54.
|
||||
|
||||
**Aktueller Stand:**
|
||||
- Expo SDK: 53.0.20
|
||||
|
|
@ -233,5 +233,5 @@ Bei Problemen während des Upgrades:
|
|||
---
|
||||
|
||||
**Letzte Aktualisierung:** 24. September 2025
|
||||
**Erstellt für:** Manadeck Projekt
|
||||
**Erstellt für:** Cards Projekt
|
||||
**SDK Version:** 53 → 54
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## Übersicht
|
||||
|
||||
Diese Anleitung beschreibt den Upgrade-Prozess von Expo SDK 53 auf SDK 54 für das Manadeck-Projekt.
|
||||
Diese Anleitung beschreibt den Upgrade-Prozess von Expo SDK 53 auf SDK 54 für das Cards-Projekt.
|
||||
|
||||
## Wichtige Änderungen in SDK 54
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ Da SDK 54 React Native 0.81 und React 19.1 benötigt:
|
|||
npm install react@19.1.0 react-native@0.81.x
|
||||
```
|
||||
|
||||
### 4. Spezifische Package-Updates für Manadeck
|
||||
### 4. Spezifische Package-Updates für Cards
|
||||
|
||||
Basierend auf den aktuellen Dependencies:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Manadeck Frontend-Komponenten Plan
|
||||
# Cards Frontend-Komponenten Plan
|
||||
|
||||
## Architektur-Übersicht
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Manadeck - Nächste Implementierungsschritte
|
||||
# Cards - Nächste Implementierungsschritte
|
||||
|
||||
## 🎯 Aktueller Status
|
||||
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ INSERT INTO auth.users (
|
|||
'00000000-0000-0000-0000-000000000001',
|
||||
'authenticated',
|
||||
'authenticated',
|
||||
'system@manadeck.app',
|
||||
'system@cards.app',
|
||||
'$2a$10$dummyhashforpassword', -- Dummy encrypted password
|
||||
now(),
|
||||
'{"provider": "system", "providers": ["system"]}',
|
||||
'{"display_name": "Manadeck System", "is_system_user": true}',
|
||||
'{"display_name": "Cards System", "is_system_user": true}',
|
||||
now(),
|
||||
now(),
|
||||
'',
|
||||
|
|
@ -45,8 +45,8 @@ INSERT INTO public.profiles (
|
|||
updated_at
|
||||
) VALUES (
|
||||
'00000000-0000-0000-0000-000000000001',
|
||||
'manadeck_system',
|
||||
'Manadeck System',
|
||||
'cards_system',
|
||||
'Cards System',
|
||||
'System account for managing public sample decks and community content.',
|
||||
'{"is_system_account": true, "can_create_public_decks": true}',
|
||||
now(),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## Überblick
|
||||
|
||||
Manadeck implementiert ein wissenschaftlich fundiertes **Spaced Repetition System (SRS)** basierend auf dem **SuperMemo 2 (SM-2) Algorithmus**. Dieses System optimiert den Lernprozess durch intelligente Wiederholungsintervalle, die sich an die individuelle Lernleistung anpassen.
|
||||
Cards implementiert ein wissenschaftlich fundiertes **Spaced Repetition System (SRS)** basierend auf dem **SuperMemo 2 (SM-2) Algorithmus**. Dieses System optimiert den Lernprozess durch intelligente Wiederholungsintervalle, die sich an die individuelle Lernleistung anpassen.
|
||||
|
||||
## Was ist Spaced Repetition?
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ Der SM-2 Algorithmus berechnet optimale Wiederholungsintervalle basierend auf:
|
|||
|
||||
### Qualitätsstufen
|
||||
|
||||
In Manadeck werden 4 Bewertungsstufen verwendet:
|
||||
In Cards werden 4 Bewertungsstufen verwendet:
|
||||
|
||||
| Button | Qualität (Q) | Bedeutung | Typisches Intervall |
|
||||
|--------|--------------|-----------|-------------------|
|
||||
|
|
@ -55,7 +55,7 @@ if (Q < 3) {
|
|||
}
|
||||
```
|
||||
|
||||
## Implementation in Manadeck
|
||||
## Implementation in Cards
|
||||
|
||||
### Datenbankstruktur
|
||||
|
||||
|
|
@ -233,7 +233,7 @@ organizeReviewQueue(cards: CardProgress[])
|
|||
|
||||
## Vergleich mit anderen Systemen
|
||||
|
||||
| Feature | Manadeck | Anki | Quizlet |
|
||||
| Feature | Cards | Anki | Quizlet |
|
||||
|---------|----------|------|---------|
|
||||
| Algorithmus | SM-2 | SM-2+ | Proprietary |
|
||||
| Open Source | ✅ | ✅ | ❌ |
|
||||
|
|
@ -268,7 +268,7 @@ organizeReviewQueue(cards: CardProgress[])
|
|||
|
||||
## Fazit
|
||||
|
||||
Das Spaced Repetition System in Manadeck bietet eine wissenschaftlich fundierte, effiziente Methode zum Langzeit-Lernen. Durch die SM-2 Implementation erreichen Nutzer optimale Lernresultate mit minimalem Zeitaufwand.
|
||||
Das Spaced Repetition System in Cards bietet eine wissenschaftlich fundierte, effiziente Methode zum Langzeit-Lernen. Durch die SM-2 Implementation erreichen Nutzer optimale Lernresultate mit minimalem Zeitaufwand.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# Decks erstellen in Manadeck
|
||||
# Decks erstellen in Cards
|
||||
|
||||
## Übersicht
|
||||
|
||||
Manadeck ermöglicht es Benutzern, eigene Lernkarten-Decks zu erstellen und zu verwalten. Diese Anleitung zeigt dir, wie du neue Decks erstellen und konfigurieren kannst.
|
||||
Cards ermöglicht es Benutzern, eigene Lernkarten-Decks zu erstellen und zu verwalten. Diese Anleitung zeigt dir, wie du neue Decks erstellen und konfigurieren kannst.
|
||||
|
||||
## Deck-Erstellung Schritt für Schritt
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ Nach der Deck-Erstellung kannst du Karten hinzufügen:
|
|||
|
||||
#### Kartentypen
|
||||
|
||||
Manadeck unterstützt verschiedene Kartentypen:
|
||||
Cards unterstützt verschiedene Kartentypen:
|
||||
|
||||
1. **Text-Karten**: Klassische Vorderseite/Rückseite Karten
|
||||
2. **Bild-Karten**: Karten mit Bildern
|
||||
|
|
@ -51,7 +51,7 @@ Manadeck unterstützt verschiedene Kartentypen:
|
|||
|
||||
### 4. KI-unterstützte Erstellung
|
||||
|
||||
Manadeck bietet KI-Features zur Deck-Erstellung:
|
||||
Cards bietet KI-Features zur Deck-Erstellung:
|
||||
|
||||
#### Smart Card Creator
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## Übersicht
|
||||
|
||||
Diese Liste enthält Vorschläge für hochwertige öffentliche Decks, die der Manadeck-Community zugute kommen würden. Diese Decks können von Admins oder erfahrenen Benutzern erstellt und als Startinhalt für die Plattform verwendet werden.
|
||||
Diese Liste enthält Vorschläge für hochwertige öffentliche Decks, die der Cards-Community zugute kommen würden. Diese Decks können von Admins oder erfahrenen Benutzern erstellt und als Startinhalt für die Plattform verwendet werden.
|
||||
|
||||
## 🌍 Sprachen
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"expo": {
|
||||
"name": "manadeck",
|
||||
"slug": "manadeck",
|
||||
"name": "cards",
|
||||
"slug": "cards",
|
||||
"version": "1.0.0",
|
||||
"scheme": "manadeck",
|
||||
"scheme": "cards",
|
||||
"runtimeVersion": {
|
||||
"policy": "appVersion"
|
||||
},
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
"assetBundlePatterns": ["**/*"],
|
||||
"ios": {
|
||||
"supportsTablet": true,
|
||||
"bundleIdentifier": "com.tilljs.manadeck",
|
||||
"bundleIdentifier": "com.tilljs.cards",
|
||||
"infoPlist": {
|
||||
"ITSAppUsesNonExemptEncryption": false,
|
||||
"NSMicrophoneUsageDescription": "Diese App benötigt Zugriff auf das Mikrofon, um Sprachaufnahmen für die Lernkarten-Erstellung zu ermöglichen.",
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
"foregroundImage": "./assets/adaptive-icon.png",
|
||||
"backgroundColor": "#ffffff"
|
||||
},
|
||||
"package": "com.tilljs.manadeck",
|
||||
"package": "com.tilljs.cards",
|
||||
"permissions": [
|
||||
"android.permission.RECORD_AUDIO",
|
||||
"android.permission.CAMERA",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// It is safe to delete this file as it does not affect the functionality of your application.
|
||||
{
|
||||
"cesVersion": "2.18.7",
|
||||
"projectName": "manadeck",
|
||||
"projectName": "cards",
|
||||
"packages": [
|
||||
{
|
||||
"name": "expo-router",
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import { useInsufficientCredits } from '../hooks/useInsufficientCredits';
|
|||
import { creditService } from '../services/creditService';
|
||||
|
||||
const BASE_API_URL =
|
||||
process.env.EXPO_PUBLIC_API_URL || 'https://manadeck-backend-111768794939.europe-west3.run.app';
|
||||
process.env.EXPO_PUBLIC_API_URL || 'https://cards-backend-111768794939.europe-west3.run.app';
|
||||
|
||||
export function DeckCreationExample() {
|
||||
const [deckName, setDeckName] = useState('');
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@manadeck/mobile",
|
||||
"name": "@cards/mobile",
|
||||
"version": "0.2.0",
|
||||
"main": "expo-router/entry",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* API Client for ManaDeck Backend
|
||||
* API Client for Cards Backend
|
||||
* Uses shared-auth TokenManager for automatic token handling
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { get } from '../utils/apiClient';
|
|||
import type { CreditBalance } from '../types/credits';
|
||||
|
||||
const BASE_API_URL =
|
||||
process.env.EXPO_PUBLIC_API_URL || 'https://manadeck-backend-111768794939.europe-west3.run.app';
|
||||
process.env.EXPO_PUBLIC_API_URL || 'https://cards-backend-111768794939.europe-west3.run.app';
|
||||
|
||||
/**
|
||||
* Credit Service
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Credit-related types for Manadeck
|
||||
* Credit-related types for Cards
|
||||
*/
|
||||
|
||||
export interface CreditBalance {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@manadeck/server",
|
||||
"name": "@cards/server",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* ManaDeck Hono Server — AI card/deck generation
|
||||
* Cards Hono Server — AI card/deck generation
|
||||
*
|
||||
* CRUD for decks/cards handled by mana-sync.
|
||||
*/
|
||||
|
|
@ -18,7 +18,7 @@ const app = new Hono();
|
|||
app.onError(errorHandler);
|
||||
app.notFound(notFoundHandler);
|
||||
app.use('*', cors({ origin: CORS_ORIGINS, credentials: true }));
|
||||
app.route('/health', healthRoute('manadeck-server'));
|
||||
app.route('/health', healthRoute('cards-server'));
|
||||
app.use('/api/*', authMiddleware());
|
||||
|
||||
// ─── AI Deck Generation (server-only: mana-llm + credits) ───
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ PUBLIC_SUPABASE_URL=https://your-project.supabase.co
|
|||
PUBLIC_SUPABASE_ANON_KEY=your-anon-key
|
||||
|
||||
# Mana Core Backend
|
||||
PUBLIC_API_URL=https://manadeck-backend-111768794939.europe-west3.run.app
|
||||
PUBLIC_API_URL=https://cards-backend-111768794939.europe-west3.run.app
|
||||
|
||||
# App Config
|
||||
PUBLIC_APP_NAME=Manadeck
|
||||
PUBLIC_APP_NAME=Cards
|
||||
PUBLIC_APP_URL=http://localhost:5173
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
FROM sveltekit-base:local AS builder
|
||||
|
||||
ARG PUBLIC_BACKEND_URL=http://manadeck-server
|
||||
ARG PUBLIC_BACKEND_URL=http://cards-server
|
||||
ARG PUBLIC_MANA_CORE_AUTH_URL=http://mana-auth:3001
|
||||
ARG PUBLIC_API_URL=http://manadeck-server
|
||||
ARG PUBLIC_API_URL=http://cards-server
|
||||
ENV PUBLIC_BACKEND_URL=$PUBLIC_BACKEND_URL
|
||||
ENV PUBLIC_MANA_CORE_AUTH_URL=$PUBLIC_MANA_CORE_AUTH_URL
|
||||
ENV PUBLIC_API_URL=$PUBLIC_API_URL
|
||||
|
||||
COPY apps/manadeck/apps/web ./apps/manadeck/apps/web
|
||||
COPY apps/cards/apps/web ./apps/cards/apps/web
|
||||
|
||||
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \
|
||||
pnpm install --no-frozen-lockfile --ignore-scripts
|
||||
|
||||
WORKDIR /app/apps/manadeck/apps/web
|
||||
WORKDIR /app/apps/cards/apps/web
|
||||
RUN pnpm exec svelte-kit sync
|
||||
RUN NODE_OPTIONS="--max-old-space-size=4096" pnpm build
|
||||
|
||||
FROM node:20-alpine AS production
|
||||
WORKDIR /app/apps/manadeck/apps/web
|
||||
WORKDIR /app/apps/cards/apps/web
|
||||
COPY --from=builder /app/node_modules/.pnpm /app/node_modules/.pnpm
|
||||
COPY --from=builder /app/apps/manadeck/apps/web/node_modules ./node_modules
|
||||
COPY --from=builder /app/apps/manadeck/apps/web/build ./build
|
||||
COPY --from=builder /app/apps/manadeck/apps/web/package.json ./
|
||||
COPY --from=builder /app/apps/cards/apps/web/node_modules ./node_modules
|
||||
COPY --from=builder /app/apps/cards/apps/web/build ./build
|
||||
COPY --from=builder /app/apps/cards/apps/web/package.json ./
|
||||
|
||||
EXPOSE 5015
|
||||
ENV NODE_ENV=production PORT=5015 HOST=0.0.0.0
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@manadeck/web",
|
||||
"name": "@cards/web",
|
||||
"private": true,
|
||||
"version": "0.2.0",
|
||||
"type": "module",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { initErrorTracking, handleSvelteError } from '@manacore/shared-error-tra
|
|||
import type { HandleClientError } from '@sveltejs/kit';
|
||||
|
||||
initErrorTracking({
|
||||
serviceName: 'manadeck-web',
|
||||
serviceName: 'cards-web',
|
||||
dsn: (window as any).__PUBLIC_GLITCHTIP_DSN__,
|
||||
environment: import.meta.env.MODE,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Feedback Service Instance for ManaDeck Web App
|
||||
* Feedback Service Instance for Cards Web App
|
||||
*/
|
||||
|
||||
import { createFeedbackService } from '@manacore/feedback';
|
||||
|
|
@ -10,6 +10,6 @@ const MANA_AUTH_URL = PUBLIC_MANA_CORE_AUTH_URL || 'http://localhost:3001';
|
|||
|
||||
export const feedbackService = createFeedbackService({
|
||||
apiUrl: MANA_AUTH_URL,
|
||||
appId: 'manadeck',
|
||||
appId: 'cards',
|
||||
getAuthToken: async () => authService.getAppToken(),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Manadeck Web Auth Configuration
|
||||
* Cards Web Auth Configuration
|
||||
*
|
||||
* This file initializes the shared auth package for the manadeck web app.
|
||||
* This file initializes the shared auth package for the cards web app.
|
||||
* It replaces the previous individual auth files:
|
||||
* - services/authService.ts
|
||||
* - services/tokenManager.ts
|
||||
|
|
@ -28,11 +28,11 @@ const STORAGE_KEYS = {
|
|||
APP_TOKEN: 'appToken',
|
||||
REFRESH_TOKEN: 'refreshToken',
|
||||
USER_EMAIL: 'userEmail',
|
||||
DEVICE_ID: 'manadeck_device_id',
|
||||
DEVICE_ID: 'cards_device_id',
|
||||
};
|
||||
|
||||
/**
|
||||
* Session storage adapter for manadeck web
|
||||
* Session storage adapter for cards web
|
||||
* Uses sessionStorage for tokens (clears on tab close)
|
||||
* Uses localStorage for device ID (persists)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { describe, it, expect } from 'vitest';
|
||||
import { getManaDeckHelpContent } from './index';
|
||||
import { getCardsHelpContent } from './index';
|
||||
|
||||
describe('ManaDeck Help Content', () => {
|
||||
describe('Cards Help Content', () => {
|
||||
it('returns valid German content', () => {
|
||||
const content = getManaDeckHelpContent('de');
|
||||
const content = getCardsHelpContent('de');
|
||||
|
||||
expect(content.faq.length).toBeGreaterThan(0);
|
||||
content.faq.forEach((faq) => {
|
||||
|
|
@ -18,7 +18,7 @@ describe('ManaDeck Help Content', () => {
|
|||
});
|
||||
|
||||
it('returns valid English content', () => {
|
||||
const content = getManaDeckHelpContent('en');
|
||||
const content = getCardsHelpContent('en');
|
||||
|
||||
expect(content.faq.length).toBeGreaterThan(0);
|
||||
content.faq.forEach((faq) => {
|
||||
|
|
@ -32,15 +32,15 @@ describe('ManaDeck Help Content', () => {
|
|||
});
|
||||
|
||||
it('returns same number of FAQ items for both languages', () => {
|
||||
const de = getManaDeckHelpContent('de');
|
||||
const en = getManaDeckHelpContent('en');
|
||||
const de = getCardsHelpContent('de');
|
||||
const en = getCardsHelpContent('en');
|
||||
|
||||
expect(de.faq.length).toBe(en.faq.length);
|
||||
expect(de.features.length).toBe(en.features.length);
|
||||
});
|
||||
|
||||
it('has unique FAQ IDs', () => {
|
||||
const content = getManaDeckHelpContent('de');
|
||||
const content = getCardsHelpContent('de');
|
||||
const ids = content.faq.map((f) => f.id);
|
||||
expect(new Set(ids).size).toBe(ids.length);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
/**
|
||||
* Help content for ManaDeck app
|
||||
* Help content for Cards app
|
||||
*/
|
||||
|
||||
import type { HelpContent } from '@manacore/help';
|
||||
import { getPrivacyFAQs } from '@manacore/help';
|
||||
|
||||
export function getManaDeckHelpContent(locale: string): HelpContent {
|
||||
export function getCardsHelpContent(locale: string): HelpContent {
|
||||
const isDE = locale === 'de';
|
||||
|
||||
return {
|
||||
|
|
@ -14,8 +14,8 @@ export function getManaDeckHelpContent(locale: string): HelpContent {
|
|||
id: 'faq-create-decks',
|
||||
question: isDE ? 'Wie erstelle ich Decks und Karten?' : 'How do I create decks and cards?',
|
||||
answer: isDE
|
||||
? '<p>So erstellst du Decks und Karten in ManaDeck:</p><ol><li>Klicke auf <strong>Neues Deck</strong> und gib einen Namen und eine Beschreibung ein</li><li>Öffne das Deck und klicke auf <strong>Karte hinzufügen</strong></li><li>Gib die <strong>Vorderseite</strong> (Frage) und <strong>Rückseite</strong> (Antwort) ein</li><li>Optional: Füge Bilder, Tags oder Notizen hinzu</li></ol><p>Du kannst auch mehrere Karten auf einmal importieren — siehe Import & Export.</p>'
|
||||
: '<p>Here is how to create decks and cards in ManaDeck:</p><ol><li>Click <strong>New Deck</strong> and enter a name and description</li><li>Open the deck and click <strong>Add Card</strong></li><li>Enter the <strong>front</strong> (question) and <strong>back</strong> (answer)</li><li>Optional: Add images, tags, or notes</li></ol><p>You can also import multiple cards at once — see Import & Export.</p>',
|
||||
? '<p>So erstellst du Decks und Karten in Cards:</p><ol><li>Klicke auf <strong>Neues Deck</strong> und gib einen Namen und eine Beschreibung ein</li><li>Öffne das Deck und klicke auf <strong>Karte hinzufügen</strong></li><li>Gib die <strong>Vorderseite</strong> (Frage) und <strong>Rückseite</strong> (Antwort) ein</li><li>Optional: Füge Bilder, Tags oder Notizen hinzu</li></ol><p>Du kannst auch mehrere Karten auf einmal importieren — siehe Import & Export.</p>'
|
||||
: '<p>Here is how to create decks and cards in Cards:</p><ol><li>Click <strong>New Deck</strong> and enter a name and description</li><li>Open the deck and click <strong>Add Card</strong></li><li>Enter the <strong>front</strong> (question) and <strong>back</strong> (answer)</li><li>Optional: Add images, tags, or notes</li></ol><p>You can also import multiple cards at once — see Import & Export.</p>',
|
||||
category: 'features',
|
||||
order: 1,
|
||||
language: isDE ? 'de' : 'en',
|
||||
|
|
@ -38,8 +38,8 @@ export function getManaDeckHelpContent(locale: string): HelpContent {
|
|||
id: 'faq-study-sessions',
|
||||
question: isDE ? 'Wie starte ich eine Lernsitzung?' : 'How do I start a study session?',
|
||||
answer: isDE
|
||||
? '<p>So startest du eine Lernsitzung:</p><ol><li>Wähle ein Deck aus deiner Bibliothek</li><li>Klicke auf <strong>Lernen</strong> — die fälligen Karten werden automatisch ausgewählt</li><li>Für jede Karte: Lies die Frage, überlege die Antwort, decke die Rückseite auf</li><li>Bewerte dein Wissen mit den Buttons: Nochmal, Schwer, Gut, Leicht</li></ol><p>ManaDeck zeigt dir an, wie viele Karten <strong>neu</strong>, <strong>fällig</strong> und <strong>zu wiederholen</strong> sind.</p>'
|
||||
: '<p>Here is how to start a study session:</p><ol><li>Select a deck from your library</li><li>Click <strong>Study</strong> — due cards are automatically selected</li><li>For each card: Read the question, think of the answer, reveal the back</li><li>Rate your knowledge with the buttons: Again, Hard, Good, Easy</li></ol><p>ManaDeck shows you how many cards are <strong>new</strong>, <strong>due</strong>, and <strong>to review</strong>.</p>',
|
||||
? '<p>So startest du eine Lernsitzung:</p><ol><li>Wähle ein Deck aus deiner Bibliothek</li><li>Klicke auf <strong>Lernen</strong> — die fälligen Karten werden automatisch ausgewählt</li><li>Für jede Karte: Lies die Frage, überlege die Antwort, decke die Rückseite auf</li><li>Bewerte dein Wissen mit den Buttons: Nochmal, Schwer, Gut, Leicht</li></ol><p>Cards zeigt dir an, wie viele Karten <strong>neu</strong>, <strong>fällig</strong> und <strong>zu wiederholen</strong> sind.</p>'
|
||||
: '<p>Here is how to start a study session:</p><ol><li>Select a deck from your library</li><li>Click <strong>Study</strong> — due cards are automatically selected</li><li>For each card: Read the question, think of the answer, reveal the back</li><li>Rate your knowledge with the buttons: Again, Hard, Good, Easy</li></ol><p>Cards shows you how many cards are <strong>new</strong>, <strong>due</strong>, and <strong>to review</strong>.</p>',
|
||||
category: 'features',
|
||||
order: 3,
|
||||
language: isDE ? 'de' : 'en',
|
||||
|
|
@ -51,8 +51,8 @@ export function getManaDeckHelpContent(locale: string): HelpContent {
|
|||
? 'Kann ich Karten importieren und exportieren?'
|
||||
: 'Can I import and export cards?',
|
||||
answer: isDE
|
||||
? '<p>ManaDeck unterstützt verschiedene Import- und Exportformate:</p><ul><li><strong>CSV</strong>: Importiere Karten aus Tabellenkalkulationen (Vorderseite, Rückseite, Tags)</li><li><strong>Anki-Format</strong>: Importiere bestehende Anki-Decks (.apkg)</li><li><strong>JSON</strong>: Für programmatischen Zugriff und Backup</li><li><strong>Export</strong>: Exportiere einzelne Decks oder deine gesamte Bibliothek</li></ul>'
|
||||
: '<p>ManaDeck supports various import and export formats:</p><ul><li><strong>CSV</strong>: Import cards from spreadsheets (front, back, tags)</li><li><strong>Anki format</strong>: Import existing Anki decks (.apkg)</li><li><strong>JSON</strong>: For programmatic access and backup</li><li><strong>Export</strong>: Export individual decks or your entire library</li></ul>',
|
||||
? '<p>Cards unterstützt verschiedene Import- und Exportformate:</p><ul><li><strong>CSV</strong>: Importiere Karten aus Tabellenkalkulationen (Vorderseite, Rückseite, Tags)</li><li><strong>Anki-Format</strong>: Importiere bestehende Anki-Decks (.apkg)</li><li><strong>JSON</strong>: Für programmatischen Zugriff und Backup</li><li><strong>Export</strong>: Exportiere einzelne Decks oder deine gesamte Bibliothek</li></ul>'
|
||||
: '<p>Cards supports various import and export formats:</p><ul><li><strong>CSV</strong>: Import cards from spreadsheets (front, back, tags)</li><li><strong>Anki format</strong>: Import existing Anki decks (.apkg)</li><li><strong>JSON</strong>: For programmatic access and backup</li><li><strong>Export</strong>: Export individual decks or your entire library</li></ul>',
|
||||
category: 'technical',
|
||||
order: 4,
|
||||
language: isDE ? 'de' : 'en',
|
||||
|
|
@ -129,8 +129,8 @@ export function getManaDeckHelpContent(locale: string): HelpContent {
|
|||
id: 'contact-support',
|
||||
title: isDE ? 'Support kontaktieren' : 'Contact Support',
|
||||
content: isDE
|
||||
? '<p>Unser Support-Team hilft dir bei allen Fragen rund um ManaDeck.</p>'
|
||||
: '<p>Our support team is here to help you with any questions about ManaDeck.</p>',
|
||||
? '<p>Unser Support-Team hilft dir bei allen Fragen rund um Cards.</p>'
|
||||
: '<p>Our support team is here to help you with any questions about Cards.</p>',
|
||||
language: isDE ? 'de' : 'en',
|
||||
order: 1,
|
||||
supportEmail: 'support@mana.how',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Guest seed data for the ManaDeck app.
|
||||
* Guest seed data for the Cards app.
|
||||
*
|
||||
* These records are loaded into IndexedDB when a new guest visits the app.
|
||||
* They serve as onboarding content that teaches the user how the app works.
|
||||
|
|
@ -13,7 +13,7 @@ export const guestDecks: LocalDeck[] = [
|
|||
{
|
||||
id: ONBOARDING_DECK_ID,
|
||||
name: 'Erste Schritte',
|
||||
description: 'Lerne ManaDeck kennen mit diesen Beispiel-Karteikarten.',
|
||||
description: 'Lerne Cards kennen mit diesen Beispiel-Karteikarten.',
|
||||
color: '#6366f1',
|
||||
cardCount: 3,
|
||||
isPublic: false,
|
||||
|
|
@ -24,8 +24,8 @@ export const guestCards: LocalCard[] = [
|
|||
{
|
||||
id: 'card-1',
|
||||
deckId: ONBOARDING_DECK_ID,
|
||||
front: 'Was ist ManaDeck?',
|
||||
back: 'ManaDeck ist eine Karteikarten-App zum effizienten Lernen mit Spaced Repetition.',
|
||||
front: 'Was ist Cards?',
|
||||
back: 'Cards ist eine Karteikarten-App zum effizienten Lernen mit Spaced Repetition.',
|
||||
difficulty: 1,
|
||||
reviewCount: 0,
|
||||
order: 0,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* ManaDeck — Local-First Data Layer
|
||||
* Cards — Local-First Data Layer
|
||||
*
|
||||
* Defines the IndexedDB database, collections, and guest seed data.
|
||||
* This is the single source of truth for all ManaDeck data.
|
||||
* This is the single source of truth for all Cards data.
|
||||
*/
|
||||
|
||||
import { createLocalStore, type BaseRecord } from '@manacore/local-store';
|
||||
|
|
@ -33,8 +33,8 @@ export interface LocalCard extends BaseRecord {
|
|||
|
||||
const SYNC_SERVER_URL = import.meta.env.PUBLIC_SYNC_SERVER_URL || 'http://localhost:3050';
|
||||
|
||||
export const manadeckStore = createLocalStore({
|
||||
appId: 'manadeck',
|
||||
export const cardsStore = createLocalStore({
|
||||
appId: 'cards',
|
||||
collections: [
|
||||
{
|
||||
name: 'decks',
|
||||
|
|
@ -53,5 +53,5 @@ export const manadeckStore = createLocalStore({
|
|||
});
|
||||
|
||||
// Typed collection accessors
|
||||
export const deckCollection = manadeckStore.collection<LocalDeck>('decks');
|
||||
export const cardCollection = manadeckStore.collection<LocalCard>('cards');
|
||||
export const deckCollection = cardsStore.collection<LocalDeck>('decks');
|
||||
export const cardCollection = cardsStore.collection<LocalCard>('cards');
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Reactive Queries & Pure Helpers for ManaDeck
|
||||
* Reactive Queries & Pure Helpers for Cards
|
||||
*
|
||||
* Uses Dexie liveQuery to automatically re-render when IndexedDB changes
|
||||
* (local writes, sync updates, other tabs). Components call these hooks
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@
|
|||
"memoro_long_desc": "Erfasse deine Gedanken durch Sprache und lasse sie von KI in strukturierte Notizen verwandeln.",
|
||||
"maerchenzauber_desc": "Magische Kindergeschichten",
|
||||
"maerchenzauber_long_desc": "Erstelle personalisierte Kindergeschichten mit KI-generierten Illustrationen.",
|
||||
"manadeck_desc": "KI Lernkarten",
|
||||
"manadeck_long_desc": "Erstelle und lerne mit smarten Lernkarten und KI-gestützter Wiederholung.",
|
||||
"cards_desc": "KI Lernkarten",
|
||||
"cards_long_desc": "Erstelle und lerne mit smarten Lernkarten und KI-gestützter Wiederholung.",
|
||||
"moodlit_desc": "Stimmungslicht-Steuerung",
|
||||
"moodlit_long_desc": "Steuere deine smarten Lichter basierend auf deiner Stimmung und Aktivität.",
|
||||
"manacore_desc": "Zentrale Verwaltung",
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@
|
|||
"memoro_long_desc": "Capture your thoughts through voice and let AI transform them into structured notes.",
|
||||
"maerchenzauber_desc": "Magical children's stories",
|
||||
"maerchenzauber_long_desc": "Create personalized children's stories with AI-generated illustrations.",
|
||||
"manadeck_desc": "AI Flashcards",
|
||||
"manadeck_long_desc": "Create and study with smart flashcards and AI-powered spaced repetition.",
|
||||
"cards_desc": "AI Flashcards",
|
||||
"cards_long_desc": "Create and study with smart flashcards and AI-powered spaced repetition.",
|
||||
"moodlit_desc": "Mood light control",
|
||||
"moodlit_long_desc": "Control your smart lights based on your mood and activity.",
|
||||
"manacore_desc": "Central management",
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@
|
|||
"memoro_long_desc": "Captura tus pensamientos con voz y deja que la IA los transforme en notas estructuradas.",
|
||||
"maerchenzauber_desc": "Historias mágicas para niños",
|
||||
"maerchenzauber_long_desc": "Crea historias personalizadas para niños con ilustraciones generadas por IA.",
|
||||
"manadeck_desc": "Flashcards IA",
|
||||
"manadeck_long_desc": "Crea y estudia con flashcards inteligentes y repetición espaciada con IA.",
|
||||
"cards_desc": "Flashcards IA",
|
||||
"cards_long_desc": "Crea y estudia con flashcards inteligentes y repetición espaciada con IA.",
|
||||
"moodlit_desc": "Control de luces ambientales",
|
||||
"moodlit_long_desc": "Controla tus luces inteligentes según tu estado de ánimo y actividades.",
|
||||
"manacore_desc": "Gestión central",
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@
|
|||
"memoro_long_desc": "Capturez vos pensées par la voix et laissez l'IA les transformer en notes structurées.",
|
||||
"maerchenzauber_desc": "Histoires magiques pour enfants",
|
||||
"maerchenzauber_long_desc": "Créez des histoires personnalisées pour enfants avec des illustrations générées par l'IA.",
|
||||
"manadeck_desc": "Flashcards IA",
|
||||
"manadeck_long_desc": "Créez et étudiez avec des flashcards intelligentes et la répétition espacée assistée par IA.",
|
||||
"cards_desc": "Flashcards IA",
|
||||
"cards_long_desc": "Créez et étudiez avec des flashcards intelligentes et la répétition espacée assistée par IA.",
|
||||
"moodlit_desc": "Contrôle d'éclairage ambiant",
|
||||
"moodlit_long_desc": "Contrôlez vos lumières intelligentes en fonction de votre humeur et de vos activités.",
|
||||
"manacore_desc": "Gestion centrale",
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@
|
|||
"memoro_long_desc": "Cattura i tuoi pensieri con la voce e lascia che l'AI li trasformi in note strutturate.",
|
||||
"maerchenzauber_desc": "Storie magiche per bambini",
|
||||
"maerchenzauber_long_desc": "Crea storie personalizzate per bambini con illustrazioni generate dall'AI.",
|
||||
"manadeck_desc": "Flashcard AI",
|
||||
"manadeck_long_desc": "Crea e studia con flashcard intelligenti e ripetizione spaziata basata su AI.",
|
||||
"cards_desc": "Flashcard AI",
|
||||
"cards_long_desc": "Crea e studia con flashcard intelligenti e ripetizione spaziata basata su AI.",
|
||||
"moodlit_desc": "Controllo luci ambientali",
|
||||
"moodlit_long_desc": "Controlla le tue luci smart in base al tuo umore e alle tue attività.",
|
||||
"manacore_desc": "Gestione centrale",
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@ import { createAppOnboardingStore, type AppOnboardingStep } from '@manacore/shar
|
|||
import { userSettings } from './user-settings.svelte';
|
||||
|
||||
/**
|
||||
* ManaDeck-specific onboarding steps
|
||||
* Cards-specific onboarding steps
|
||||
*/
|
||||
const manadeckOnboardingSteps: AppOnboardingStep[] = [
|
||||
const cardsOnboardingSteps: AppOnboardingStep[] = [
|
||||
{
|
||||
id: 'features',
|
||||
type: 'info',
|
||||
question: 'Willkommen bei ManaDeck!',
|
||||
description: 'Das kann ManaDeck für dich tun:',
|
||||
question: 'Willkommen bei Cards!',
|
||||
description: 'Das kann Cards für dich tun:',
|
||||
emoji: '🃏',
|
||||
gradient: { from: 'blue-500', to: 'blue-700' },
|
||||
bullets: [
|
||||
|
|
@ -51,7 +51,7 @@ const manadeckOnboardingSteps: AppOnboardingStep[] = [
|
|||
{
|
||||
id: 'welcome',
|
||||
type: 'info',
|
||||
question: 'ManaDeck ist bereit!',
|
||||
question: 'Cards ist bereit!',
|
||||
description: 'Hier sind einige Tipps:',
|
||||
emoji: '🎉',
|
||||
gradient: { from: 'primary', to: 'primary/70' },
|
||||
|
|
@ -65,11 +65,11 @@ const manadeckOnboardingSteps: AppOnboardingStep[] = [
|
|||
];
|
||||
|
||||
/**
|
||||
* ManaDeck app onboarding store
|
||||
* Cards app onboarding store
|
||||
*/
|
||||
export const manadeckOnboarding = createAppOnboardingStore({
|
||||
appId: 'manadeck',
|
||||
steps: manadeckOnboardingSteps,
|
||||
export const cardsOnboarding = createAppOnboardingStore({
|
||||
appId: 'cards',
|
||||
steps: cardsOnboardingSteps,
|
||||
userSettings,
|
||||
onComplete: async () => {},
|
||||
onSkip: async () => {},
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
import type { Card, CreateCardInput, UpdateCardInput } from '$lib/types/card';
|
||||
import { cardCollection, deckCollection, type LocalCard } from '$lib/data/local-store';
|
||||
import { toCard } from '$lib/data/queries';
|
||||
import { ManaDeckEvents } from '@manacore/shared-utils/analytics';
|
||||
import { CardsEvents } from '@manacore/shared-utils/analytics';
|
||||
|
||||
let error = $state<string | null>(null);
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ export const cardStore = {
|
|||
});
|
||||
}
|
||||
|
||||
ManaDeckEvents.cardCreated();
|
||||
CardsEvents.cardCreated();
|
||||
return toCard(inserted);
|
||||
} catch (err: any) {
|
||||
error = err.message || 'Failed to create card';
|
||||
|
|
@ -94,7 +94,7 @@ export const cardStore = {
|
|||
}
|
||||
}
|
||||
|
||||
ManaDeckEvents.cardDeleted();
|
||||
CardsEvents.cardDeleted();
|
||||
} catch (err: any) {
|
||||
error = err.message || 'Failed to delete card';
|
||||
console.error('Delete card error:', err);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
import type { CreateDeckInput, UpdateDeckInput } from '$lib/types/deck';
|
||||
import { deckCollection, cardCollection, type LocalDeck } from '$lib/data/local-store';
|
||||
import { toDeck } from '$lib/data/queries';
|
||||
import { ManaDeckEvents } from '@manacore/shared-utils/analytics';
|
||||
import { CardsEvents } from '@manacore/shared-utils/analytics';
|
||||
import type { Deck } from '$lib/types/deck';
|
||||
|
||||
let error = $state<string | null>(null);
|
||||
|
|
@ -35,7 +35,7 @@ export const deckStore = {
|
|||
};
|
||||
|
||||
const inserted = await deckCollection.insert(newLocal);
|
||||
ManaDeckEvents.deckCreated();
|
||||
CardsEvents.deckCreated();
|
||||
return toDeck(inserted);
|
||||
} catch (err: any) {
|
||||
error = err.message || 'Failed to create deck';
|
||||
|
|
@ -75,7 +75,7 @@ export const deckStore = {
|
|||
}
|
||||
|
||||
await deckCollection.delete(id);
|
||||
ManaDeckEvents.deckDeleted();
|
||||
CardsEvents.deckDeleted();
|
||||
} catch (err: any) {
|
||||
error = err.message || 'Failed to delete deck';
|
||||
console.error('Delete deck error:', err);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* ManaDeck Theme Store
|
||||
* Cards Theme Store
|
||||
*
|
||||
* Uses the shared theme system with ManaDeck's indigo primary color.
|
||||
* Uses the shared theme system with Cards's indigo primary color.
|
||||
*/
|
||||
import { createThemeStore } from '@manacore/shared-theme';
|
||||
|
||||
|
|
@ -9,14 +9,14 @@ import { createThemeStore } from '@manacore/shared-theme';
|
|||
export type { ThemeMode, ThemeVariant, EffectiveMode } from '@manacore/shared-theme';
|
||||
|
||||
/**
|
||||
* ManaDeck theme store instance
|
||||
* Cards theme store instance
|
||||
*
|
||||
* - Default variant: ocean (blue)
|
||||
* - Custom primary: Indigo (#6366f1)
|
||||
* - All 4 theme variants available
|
||||
*/
|
||||
export const theme = createThemeStore({
|
||||
appId: 'manadeck',
|
||||
appId: 'cards',
|
||||
defaultVariant: 'ocean',
|
||||
primaryColor: {
|
||||
light: '239 84% 67%', // Indigo #6366f1
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* User Settings Store for ManaDeck
|
||||
* User Settings Store for Cards
|
||||
*
|
||||
* This store syncs settings with mana-core-auth and provides:
|
||||
* - Global settings that apply to all apps
|
||||
|
|
@ -21,7 +21,7 @@ function getAuthUrl(): string {
|
|||
}
|
||||
|
||||
export const userSettings = createUserSettingsStore({
|
||||
appId: 'manadeck',
|
||||
appId: 'cards',
|
||||
authUrl: getAuthUrl,
|
||||
getAccessToken: () => authStore.getAccessToken(),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -26,14 +26,14 @@
|
|||
import { getPillAppItems, getManaApp } from '@manacore/shared-branding';
|
||||
import { setLocale, supportedLocales } from '$lib/i18n';
|
||||
import { useAllDecks } from '$lib/data/queries';
|
||||
import { manadeckOnboarding } from '$lib/stores/app-onboarding.svelte';
|
||||
import { cardsOnboarding } from '$lib/stores/app-onboarding.svelte';
|
||||
import { MiniOnboardingModal } from '@manacore/shared-app-onboarding';
|
||||
import { SessionExpiredBanner, AuthGate, GuestWelcomeModal } from '@manacore/shared-auth-ui';
|
||||
import { shouldShowGuestWelcome } from '@manacore/shared-auth-ui';
|
||||
import { manadeckStore } from '$lib/data/local-store';
|
||||
import { cardsStore } from '$lib/data/local-store';
|
||||
|
||||
// App switcher items
|
||||
let appItems = $derived(getPillAppItems('manadeck', undefined, undefined, authStore.user?.tier));
|
||||
let appItems = $derived(getPillAppItems('cards', undefined, undefined, authStore.user?.tier));
|
||||
|
||||
// Live queries — auto-update when IndexedDB changes (local writes, sync, other tabs)
|
||||
const allDecks = useAllDecks();
|
||||
|
|
@ -56,7 +56,7 @@
|
|||
isTagStripVisible = !isTagStripVisible;
|
||||
}
|
||||
|
||||
// Base navigation items for ManaDeck (Mana and Profile are in user dropdown)
|
||||
// Base navigation items for Cards (Mana and Profile are in user dropdown)
|
||||
const baseNavItems: PillNavItem[] = [
|
||||
{ href: '/decks', label: 'Decks', icon: 'archive' },
|
||||
{ href: '/explore', label: 'Explore', icon: 'search' },
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
|
||||
// Navigation items filtered by visibility settings (with fallback for guest mode)
|
||||
const navItems = $derived(
|
||||
filterHiddenNavItems('manadeck', baseNavItems, userSettings.nav?.hiddenNavItems || {})
|
||||
filterHiddenNavItems('cards', baseNavItems, userSettings.nav?.hiddenNavItems || {})
|
||||
);
|
||||
|
||||
// Get pinned themes from user settings (extended themes only)
|
||||
|
|
@ -156,7 +156,7 @@
|
|||
isCollapsed = collapsed;
|
||||
collapsedStore.set(collapsed);
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
localStorage.setItem('manadeck-nav-collapsed', String(collapsed));
|
||||
localStorage.setItem('cards-nav-collapsed', String(collapsed));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -192,17 +192,17 @@
|
|||
|
||||
async function handleAuthReady() {
|
||||
// Initialize local-first database and shared tag store
|
||||
await Promise.all([manadeckStore.initialize(), tagLocalStore.initialize()]);
|
||||
await Promise.all([cardsStore.initialize(), tagLocalStore.initialize()]);
|
||||
|
||||
// If authenticated, start syncing to server
|
||||
if (authStore.isAuthenticated) {
|
||||
const getToken = () => authStore.getValidToken();
|
||||
manadeckStore.startSync(getToken);
|
||||
cardsStore.startSync(getToken);
|
||||
tagMutations.startSync(getToken);
|
||||
}
|
||||
|
||||
// Show guest welcome modal on first visit
|
||||
if (!authStore.isAuthenticated && shouldShowGuestWelcome('manadeck')) {
|
||||
if (!authStore.isAuthenticated && shouldShowGuestWelcome('cards')) {
|
||||
showGuestWelcome = true;
|
||||
}
|
||||
|
||||
|
|
@ -218,7 +218,7 @@
|
|||
}
|
||||
|
||||
// Initialize collapsed state from localStorage
|
||||
const savedCollapsed = localStorage.getItem('manadeck-nav-collapsed');
|
||||
const savedCollapsed = localStorage.getItem('cards-nav-collapsed');
|
||||
if (savedCollapsed === 'true') {
|
||||
isCollapsed = true;
|
||||
collapsedStore.set(true);
|
||||
|
|
@ -233,15 +233,15 @@
|
|||
{goto}
|
||||
allowGuest={true}
|
||||
onReady={handleAuthReady}
|
||||
requiredTier={getManaApp('manadeck')?.requiredTier}
|
||||
appName={getManaApp('manadeck')?.name}
|
||||
requiredTier={getManaApp('cards')?.requiredTier}
|
||||
appName={getManaApp('cards')?.name}
|
||||
>
|
||||
<div class="min-h-screen bg-background">
|
||||
<!-- Pill Navigation -->
|
||||
<PillNavigation
|
||||
items={navItems}
|
||||
currentPath={$page.url.pathname}
|
||||
appName="ManaDeck"
|
||||
appName="Cards"
|
||||
homeRoute="/decks"
|
||||
onLogout={handleSignOut}
|
||||
onToggleTheme={handleToggleTheme}
|
||||
|
|
@ -307,13 +307,13 @@
|
|||
</div>
|
||||
|
||||
<!-- Onboarding Modal -->
|
||||
{#if manadeckOnboarding.shouldShow}
|
||||
<MiniOnboardingModal store={manadeckOnboarding} appName="ManaDeck" appEmoji="🃏" />
|
||||
{#if cardsOnboarding.shouldShow}
|
||||
<MiniOnboardingModal store={cardsOnboarding} appName="Cards" appEmoji="🃏" />
|
||||
{/if}
|
||||
|
||||
<!-- Guest Welcome Modal -->
|
||||
<GuestWelcomeModal
|
||||
appId="manadeck"
|
||||
appId="cards"
|
||||
visible={showGuestWelcome}
|
||||
onClose={() => (showGuestWelcome = false)}
|
||||
onLogin={() => goto('/login')}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
</script>
|
||||
|
||||
<div class="apps-page-wrapper">
|
||||
<AppsPage currentAppId="manadeck" locale="de" title="Alle Apps" />
|
||||
<AppsPage currentAppId="cards" locale="de" title="Alle Apps" />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>My Decks - Manadeck</title>
|
||||
<title>My Decks - Cards</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="space-y-6">
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{currentDeck.value?.title || 'Deck'} - Manadeck</title>
|
||||
<title>{currentDeck.value?.title || 'Deck'} - Cards</title>
|
||||
</svelte:head>
|
||||
|
||||
{#if currentDeck.value}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Explore - Manadeck</title>
|
||||
<title>Explore - Cards</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="space-y-6">
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@
|
|||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
</script>
|
||||
|
||||
<FeedbackPage {feedbackService} appName="ManaDeck" currentUserId={authStore.user?.id} />
|
||||
<FeedbackPage {feedbackService} appName="Cards" currentUserId={authStore.user?.id} />
|
||||
|
|
|
|||
|
|
@ -2,27 +2,27 @@
|
|||
import { goto } from '$app/navigation';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { HelpPage, getHelpTranslations } from '@manacore/help';
|
||||
import { getManaDeckHelpContent } from '$lib/content/help/index.js';
|
||||
import { getCardsHelpContent } from '$lib/content/help/index.js';
|
||||
|
||||
const content = $derived(getManaDeckHelpContent($locale ?? 'de'));
|
||||
const content = $derived(getCardsHelpContent($locale ?? 'de'));
|
||||
const translations = $derived(
|
||||
getHelpTranslations($locale ?? 'de', {
|
||||
subtitle:
|
||||
$locale === 'de'
|
||||
? 'Finde Antworten und lerne ManaDeck kennen'
|
||||
: 'Find answers and learn how to use ManaDeck',
|
||||
? 'Finde Antworten und lerne Cards kennen'
|
||||
: 'Find answers and learn how to use Cards',
|
||||
})
|
||||
);
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{translations.title} | ManaDeck</title>
|
||||
<title>{translations.title} | Cards</title>
|
||||
</svelte:head>
|
||||
|
||||
<HelpPage
|
||||
{content}
|
||||
appName="ManaDeck"
|
||||
appId="manadeck"
|
||||
appName="Cards"
|
||||
appId="cards"
|
||||
{translations}
|
||||
showBackButton
|
||||
onBack={() => goto('/')}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
</script>
|
||||
|
||||
<SubscriptionPage
|
||||
appName="ManaDeck"
|
||||
appName="Cards"
|
||||
onSubscribe={handleSubscribe}
|
||||
onBuyPackage={handleBuyPackage}
|
||||
currentPlanId="free"
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
<ProfilePage
|
||||
user={userProfile}
|
||||
appName="Manadeck"
|
||||
appName="Cards"
|
||||
{actions}
|
||||
pageTitle="Profil"
|
||||
accountInfoTitle="Konto-Informationen"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Progress - Manadeck</title>
|
||||
<title>Progress - Cards</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="space-y-6">
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Einstellungen - ManaDeck</title>
|
||||
<title>Einstellungen - Cards</title>
|
||||
</svelte:head>
|
||||
|
||||
<SettingsPage title="Einstellungen" subtitle="Passe die App an deine Vorlieben an.">
|
||||
<!-- Global Settings Section (synced across all apps) -->
|
||||
<GlobalSettingsSection {userSettings} appId="manadeck" />
|
||||
<GlobalSettingsSection {userSettings} appId="cards" />
|
||||
|
||||
<!-- About Section -->
|
||||
<SettingsSection title="Über">
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Tags | ManaDeck</title>
|
||||
<title>Tags | Cards</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="tags-page">
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Themes | ManaDeck</title>
|
||||
<title>Themes | Cards</title>
|
||||
</svelte:head>
|
||||
|
||||
<ThemePage
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { ForgotPasswordPage } from '@manacore/shared-auth-ui';
|
||||
import { ManaDeckLogo } from '@manacore/shared-branding';
|
||||
import { CardsLogo } from '@manacore/shared-branding';
|
||||
import AppSlider from '$lib/components/AppSlider.svelte';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
|
||||
|
|
@ -11,8 +11,8 @@
|
|||
</script>
|
||||
|
||||
<ForgotPasswordPage
|
||||
appName="ManaDeck"
|
||||
logo={ManaDeckLogo}
|
||||
appName="Cards"
|
||||
logo={CardsLogo}
|
||||
primaryColor="#8b5cf6"
|
||||
onForgotPassword={handleForgotPassword}
|
||||
{goto}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import { page } from '$app/stores';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { LoginPage } from '@manacore/shared-auth-ui';
|
||||
import { ManaDeckLogo } from '@manacore/shared-branding';
|
||||
import { CardsLogo } from '@manacore/shared-branding';
|
||||
import { getLoginTranslations } from '@manacore/shared-i18n';
|
||||
import AppSlider from '$lib/components/AppSlider.svelte';
|
||||
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
|
||||
|
|
@ -27,8 +27,8 @@
|
|||
</script>
|
||||
|
||||
<LoginPage
|
||||
appName="ManaDeck"
|
||||
logo={ManaDeckLogo}
|
||||
appName="Cards"
|
||||
logo={CardsLogo}
|
||||
primaryColor="#8b5cf6"
|
||||
onSignIn={handleSignIn}
|
||||
onResendVerification={handleResendVerification}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import { locale } from 'svelte-i18n';
|
||||
import { RegisterPage } from '@manacore/shared-auth-ui';
|
||||
import { getRegisterTranslations } from '@manacore/shared-i18n';
|
||||
import { ManaDeckLogo } from '@manacore/shared-branding';
|
||||
import { CardsLogo } from '@manacore/shared-branding';
|
||||
import AppSlider from '$lib/components/AppSlider.svelte';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import '$lib/i18n';
|
||||
|
|
@ -21,12 +21,12 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{translations.title} | ManaDeck</title>
|
||||
<title>{translations.title} | Cards</title>
|
||||
</svelte:head>
|
||||
|
||||
<RegisterPage
|
||||
appName="ManaDeck"
|
||||
logo={ManaDeckLogo}
|
||||
appName="Cards"
|
||||
logo={CardsLogo}
|
||||
primaryColor="#8b5cf6"
|
||||
onSignUp={handleSignUp}
|
||||
onResendVerification={handleResendVerification}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { onMount } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { goto } from '$app/navigation';
|
||||
import { ManaDeckLogo } from '@manacore/shared-branding';
|
||||
import { CardsLogo } from '@manacore/shared-branding';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
|
||||
let loading = $state(false);
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Reset Password - ManaDeck</title>
|
||||
<title>Reset Password - Cards</title>
|
||||
</svelte:head>
|
||||
|
||||
<div
|
||||
|
|
@ -61,8 +61,8 @@
|
|||
>
|
||||
<header class="flex items-center justify-between p-4">
|
||||
<a href="/" class="flex items-center gap-2">
|
||||
<ManaDeckLogo class="h-8 w-8" />
|
||||
<span class="text-xl font-semibold" style="color: #8b5cf6">ManaDeck</span>
|
||||
<CardsLogo class="h-8 w-8" />
|
||||
<span class="text-xl font-semibold" style="color: #8b5cf6">Cards</span>
|
||||
</a>
|
||||
</header>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import type { RequestHandler } from './$types';
|
|||
export const GET: RequestHandler = async () => {
|
||||
return json({
|
||||
status: 'ok',
|
||||
service: 'manadeck-web',
|
||||
service: 'cards-web',
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
</script>
|
||||
|
||||
<OfflinePage
|
||||
appName="ManaDeck"
|
||||
offlineMessage="ManaDeck benötigt eine Internetverbindung für deine Kartendecks."
|
||||
appName="Cards"
|
||||
offlineMessage="Cards benötigt eine Internetverbindung für deine Kartendecks."
|
||||
accentColor="#d97706"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ export default defineConfig({
|
|||
sveltekit(),
|
||||
SvelteKitPWA(
|
||||
createPWAConfig({
|
||||
name: 'ManaDeck - Kartendecks',
|
||||
shortName: 'ManaDeck',
|
||||
name: 'Cards - Kartendecks',
|
||||
shortName: 'Cards',
|
||||
description: 'Kartendecks erstellen und lernen',
|
||||
themeColor: '#f59e0b',
|
||||
})
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
"title": "Weitere Manacore Apps",
|
||||
"memoro_desc": "KI-gestützte Sprachmemos",
|
||||
"maerchenzauber_desc": "Magische Gute-Nacht-Geschichten",
|
||||
"manadeck_desc": "KI Lernkarten",
|
||||
"cards_desc": "KI Lernkarten",
|
||||
"picture_desc": "KI Bildgenerierung",
|
||||
"moodlit_desc": "Dein Stimmungsbegleiter",
|
||||
"manacore_desc": "KI-Produktivitätssuite",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
"title": "More Manacore Apps",
|
||||
"memoro_desc": "AI-powered voice memos",
|
||||
"maerchenzauber_desc": "Magical bedtime stories",
|
||||
"manadeck_desc": "AI flashcards",
|
||||
"cards_desc": "AI flashcards",
|
||||
"picture_desc": "AI image generation",
|
||||
"moodlit_desc": "Your mood companion",
|
||||
"manacore_desc": "AI productivity suite",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
"title": "Más Apps de Manacore",
|
||||
"memoro_desc": "Notas de voz con IA",
|
||||
"maerchenzauber_desc": "Cuentos mágicos para dormir",
|
||||
"manadeck_desc": "Flashcards con IA",
|
||||
"cards_desc": "Flashcards con IA",
|
||||
"picture_desc": "Generación de imágenes con IA",
|
||||
"moodlit_desc": "Tu compañero de ánimo",
|
||||
"manacore_desc": "Suite de productividad IA",
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue