diff --git a/.github/readme-assets/banner.png b/.github/readme-assets/banner.png new file mode 100644 index 0000000..6e8de2d Binary files /dev/null and b/.github/readme-assets/banner.png differ diff --git a/README.md b/README.md index 25bcc86..bf55048 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,27 @@ -
+
+
+ A tool to make board games for Print & Play and Tabletop Simulator. +
+ +--- + +## About + +Designing board games is hard. It requires **rapid iteration** and the ability to make changes **on-the-fly**. CardGoose makes it easier with data-driven components and custom templates to build your ideas in minutes. + +## Key Features + +- Import data from Google Sheets & refresh for live updates +- Component layout editor for card design + - Deck preview to evaluate changes +- Custom images +- PDF export +- TTS export (coming soon) + +# Getting started ## Prerequisites @@ -19,51 +38,40 @@ Pick one path. They differ by **where Postgres and object/queue services run**, not by repo layout. + | Mode | Frontend | API & worker | Database | Buckets & queue | | --------------- | -------- | ------------ | -------- | --------------------- | | **Fully local** | Your Mac | Your Mac | Docker | LocalStack (emulated) | | **Hybrid** | Your Mac | Your Mac | AWS RDS | AWS S3 & SQS | -| **Production** | ECS\* | ECS | AWS RDS | AWS S3 & SQS | +| **Production** | ECS | ECS | AWS RDS | AWS S3 & SQS | + -\*The API container can serve the built SPA in production (`NODE_ENV=production`). Until you add a stable URL (ALB, CloudFront, etc.), you may use the task public IP for smoke tests. +The API container can serve the built SPA in production (`NODE_ENV=production`). Until you add a stable URL (ALB, CloudFront, etc.), you may use the task public IP for smoke tests. ### Fully local (Docker Postgres + LocalStack) Use this when you want **no AWS calls**: everything emulated or on your machine. 1. **Start backing services** (Postgres on host port **5433**, LocalStack on **4566**): - - ```bash + ```bash pnpm docker:up - ``` - + ``` Optional: `docker compose build` if you use the `api` / `worker` compose services. - -2. **Configure** [`.env.local.example`](.env.local.example) → **`.env.local`** at the repo root using the **“full local stack”** block: `DATABASE_URL` pointing at `localhost:5433`, `AWS_ENDPOINT_URL=http://localhost:4566`, and bucket/queue names **`cardgoose-*`** (they must match [`docker-compose.yml`](docker-compose.yml) and [`docker/localstack-ready.d/init-aws.sh`](docker/localstack-ready.d/init-aws.sh)). - +2. **Configure** `[.env.local.example](.env.local.example)` → `**.env.local`** at the repo root using the **“full local stack”** block: `DATABASE_URL` pointing at `localhost:5433`, `AWS_ENDPOINT_URL=http://localhost:4566`, and bucket/queue names `**cardgoose-*`** (they must match `[docker-compose.yml](docker-compose.yml)` and `[docker/localstack-ready.d/init-aws.sh](docker/localstack-ready.d/init-aws.sh)`). 3. **Migrations:** - - ```bash + ```bash pnpm migrate:deploy - ``` - + ``` 4. **Run three processes** (three terminals from the repo root): - - ```bash + ```bash pnpm dev:api pnpm dev:frontend - ``` - - ```bash - cd worker - PYTHONPATH=src python3 -m baker.main - ``` - + ``` 5. Open the URL Vite prints (often `http://localhost:5173`). -Do **not** set `VITE_API_URL` in `frontend/.env.local` if the Vite dev server should proxy `/api` and `/health` to `http://localhost:3001` (see [`frontend/vite.config.ts`](frontend/vite.config.ts)). +Do **not** set `VITE_API_URL` in `frontend/.env.local` if the Vite dev server should proxy `/api` and `/health` to `http://localhost:3001` (see `[frontend/vite.config.ts](frontend/vite.config.ts)`). -**PDF exports:** set **`RENDER_URL`** in `.env.local` to the exact origin Vite prints (including port). If the worker runs in Docker and Vite on the host, use something like `http://host.docker.internal:5173`. Restart the worker after changes. +**PDF exports:** set `**RENDER_URL`** in `.env.local` to the exact origin Vite prints (including port). If the worker runs in Docker and Vite on the host, use something like `http://host.docker.internal:5173`. Restart the worker after changes. --- @@ -71,16 +79,16 @@ Do **not** set `VITE_API_URL` in `frontend/.env.local` if the Vite dev server sh Use this for day-to-day work: **Vite, the API, and the worker on your laptop** with **real RDS, S3, and SQS** in `us-east-1`. You get hot reload without deploying containers. -**1. Terraform (occasional)** — in [`infra/envs/prod`](infra/envs/prod): +**1. Terraform (occasional)** — in `[infra/envs/prod](infra/envs/prod)`: -- Allow your laptop to reach RDS: set `rds_dev_access_cidrs` without committing real IPs — e.g. `export TF_VAR_rds_dev_access_cidrs='["YOUR.PUBLIC.IP/32"]'` before `terraform apply`, or copy [`infra/envs/prod/rds.auto.tfvars.example`](infra/envs/prod/rds.auto.tfvars.example) to **`rds.auto.tfvars`** (gitignored). Update when your IP changes. +- Allow your laptop to reach RDS: set `rds_dev_access_cidrs` without committing real IPs — e.g. `export TF_VAR_rds_dev_access_cidrs='["YOUR.PUBLIC.IP/32"]'` before `terraform apply`, or copy `[infra/envs/prod/rds.auto.tfvars.example](infra/envs/prod/rds.auto.tfvars.example)` to `**rds.auto.tfvars`** (gitignored). Update when your IP changes. - Set `ecs_desired_count = 0` for the **worker** service if you run the Python worker locally (avoids two consumers on the same SQS queue and idle Fargate cost). - Run `terraform apply`. -**2. Root `.env.local`** — copy [`.env.local.example`](.env.local.example) and fill **real** values: +**2. Root `.env.local`** — copy `[.env.local.example](.env.local.example)` and fill **real** values: -- **`DATABASE_URL`** — RDS host, user `forge`, password from `terraform output -raw rds_master_password`, database name from your RDS instance (by default Terraform uses the `project_name` value, e.g. `cardboardforge`). -- **`S3_BUCKET_ASSETS`**, **`S3_BUCKET_EXPORTS`**, **`SQS_QUEUE_URL`** — from `terraform output` (`assets_bucket_name`, `exports_bucket_name`, `pdf_queue_url`). +- `**DATABASE_URL`** — RDS host, user `forge`, password from `terraform output -raw rds_master_password`, database name from your RDS instance (by default Terraform uses the `project_name` value, e.g. `cardboardforge`). +- `**S3_BUCKET_ASSETS**`, `**S3_BUCKET_EXPORTS**`, `**SQS_QUEUE_URL**` — from `terraform output` (`assets_bucket_name`, `exports_bucket_name`, `pdf_queue_url`). Do **not** set `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / `AWS_ENDPOINT_URL` for real AWS: use the default credential chain (`~/.aws/credentials` or SSO). @@ -96,7 +104,7 @@ pnpm migrate:deploy **Queue contention:** if the **ECS worker** is scaled up, it shares the same SQS URL as your laptop. For predictable local PDF debugging, keep ECS worker desired count at **0** while testing locally. -**Frontend-only against a cloud API:** set `VITE_API_URL=http://