setup local dev env
This commit is contained in:
139
README.md
139
README.md
@@ -1,66 +1,97 @@
|
||||
Root
|
||||
- .gitignore, pnpm-workspace.yaml, package.json (workspace scripts), Cargo.toml (workspace), .npmrc
|
||||
|
||||
rulesets/ — @campaign-manager/rulesets workspace package
|
||||
- types.ts — Ruleset, SheetData, ValidationResult, DiceAction, StatBlock, VNode interfaces
|
||||
- dsa5e/index.ts — DSA5e stub (typed default sheet with attributes, talents, combat, spells)
|
||||
- generic/index.ts — Generic stub (name, HP, notes)
|
||||
- index.ts — re-exports everything + RULESETS registry map
|
||||
# Campaign Manager
|
||||
|
||||
symbiote/ — Plain Svelte + Vite (target es2022 for top-level await support)
|
||||
- vite.config.ts, tsconfig.json, index.html
|
||||
- public/manifest.json — valid TaleSpire manifest with colorStyles, fonts, diceFinder, icons extras
|
||||
- src/lib/ts-api.d.ts — ambient TS global (storage, dice, players, sync)
|
||||
- src/lib/store.ts — accessToken, refreshToken, currentUser, currentGroup, isBoardTransition stores +
|
||||
loadTokens/saveTokens/clearTokens via TS.storage
|
||||
- src/lib/api.ts — auto-refresh on 401, suppresses calls during board transition
|
||||
- src/App.svelte — currentView store drives view switching
|
||||
- src/main.ts — board transition listeners, awaits TS.hasInitialized, mounts App
|
||||
- src/views/ — Login, GroupList, GroupDetail, CharacterSheet, RollHistory stubs
|
||||
Campaign Manager is split into two Rust backend services, a SvelteKit web app, and a TaleSpire Symbiote frontend.
|
||||
|
||||
web/ — SvelteKit + adapter-static
|
||||
- svelte.config.js, vite.config.ts, tsconfig.json, src/app.html
|
||||
- src/lib/api.ts — access token in memory, refresh via HttpOnly cookie
|
||||
- src/routes/+layout.svelte — silent token refresh on mount, redirects to /login if unauthenticated
|
||||
- All routes stubbed: /, /login, /groups, /groups/[id], /groups/[id]/settings, /characters, /characters/[id]
|
||||
## Architecture
|
||||
|
||||
backend/ — Rust + Axum
|
||||
- Cargo.toml with all specified dependencies
|
||||
- src/main.rs — reads DATABASE_URL/JWT_SECRET, builds Axum router, CORS, tracing, binds :3000
|
||||
- src/lib.rs — module entrypoint
|
||||
- `backend/common`: shared Rust crate for JWT and API error primitives.
|
||||
- `backend/campaign-service`: auth + campaign domain service.
|
||||
- `backend/content-service`: ruleset/content domain service.
|
||||
- `web`: SvelteKit Node server that uses server-side BFF proxy routes (`/api/*`).
|
||||
- `symbiote`: static Svelte app for TaleSpire.
|
||||
|
||||
Verification results: ✅ symbiote build → dist/ with index.html + manifest.json ✅ web build → SvelteKit static output
|
||||
✅ cargo check → no errors
|
||||
## Data layout
|
||||
|
||||
All databases run on one Postgres instance with separate logical databases:
|
||||
|
||||
Local dev workflow is now:
|
||||
|
||||
# Start Postgres
|
||||
docker compose up -d
|
||||
|
||||
# Copy and fill in secrets
|
||||
cp .env.example .env
|
||||
- `cm_users`: users/auth/session data.
|
||||
- `cm_campaign`: campaign and character data.
|
||||
- `cm_content`: rulesets/content data.
|
||||
|
||||
# Run backend
|
||||
cd backend && cargo run
|
||||
## Environment
|
||||
|
||||
# Symbiote (build-watch mode — see below)
|
||||
pnpm dev:symbiote
|
||||
Copy `.env.example` to `.env` and set values.
|
||||
|
||||
# Web app
|
||||
pnpm dev:web Local dev workflow is now:
|
||||
|
||||
# Start Postgres
|
||||
docker compose up -d
|
||||
|
||||
# Copy and fill in secrets
|
||||
cp .env.example .env
|
||||
Important variables:
|
||||
|
||||
# Run backend
|
||||
cd backend && cargo run
|
||||
- `USERS_DATABASE_URL`
|
||||
- `CAMPAIGN_DATABASE_URL`
|
||||
- `CONTENT_DATABASE_URL`
|
||||
- `JWT_SECRET`
|
||||
- `CAMPAIGN_API_BASE` / `CONTENT_API_BASE` (web BFF upstreams)
|
||||
- `VITE_CAMPAIGN_API_BASE` / `VITE_CONTENT_API_BASE` (symbiote build-time)
|
||||
|
||||
# Symbiote (build-watch mode — see below)
|
||||
pnpm dev:symbiote
|
||||
## Local development
|
||||
|
||||
# Web app
|
||||
pnpm dev:web
|
||||
```bash
|
||||
# Install JS dependencies
|
||||
pnpm install
|
||||
|
||||
# Run campaign service
|
||||
pnpm dev:campaign
|
||||
|
||||
# Run content service
|
||||
pnpm dev:content
|
||||
|
||||
# Run web app (SvelteKit dev server)
|
||||
pnpm dev:web
|
||||
|
||||
# Run symbiote app
|
||||
pnpm dev:symbiote
|
||||
```
|
||||
|
||||
Build commands:
|
||||
|
||||
```bash
|
||||
pnpm build:campaign
|
||||
pnpm build:content
|
||||
pnpm build:backend
|
||||
pnpm build:web
|
||||
pnpm build:symbiote
|
||||
```
|
||||
|
||||
Run the same checks as CI locally:
|
||||
|
||||
```bash
|
||||
pnpm ci:local
|
||||
```
|
||||
|
||||
## Web BFF routes
|
||||
|
||||
The web app proxies backend calls via SvelteKit server routes:
|
||||
|
||||
- `/api/auth/*` -> campaign service (`CAMPAIGN_API_BASE`)
|
||||
- `/api/campaign/*` -> campaign service (`CAMPAIGN_API_BASE`)
|
||||
- `/api/content/*` -> content service (`CONTENT_API_BASE`)
|
||||
|
||||
The web app is intended to run as a server process (Node adapter) in production.
|
||||
|
||||
## Docker compose
|
||||
|
||||
`docker-compose.yml` runs both backend services plus the web server and expects an external `dev-infra` network for Postgres connectivity.
|
||||
|
||||
## Woodpecker without Public Ingress
|
||||
|
||||
If your Gitea is remote and your Woodpecker server runs locally, push/PR webhooks cannot reach your machine without a public endpoint.
|
||||
|
||||
Recommended workflow until ingress/tunnel exists:
|
||||
|
||||
- Run `pnpm ci:local` before push.
|
||||
- Use local Woodpecker only for manual runs.
|
||||
|
||||
Local stack files are in `../../infra/woodpecker` from this directory:
|
||||
|
||||
```bash
|
||||
cp ../../infra/woodpecker/.env.example ../../infra/woodpecker/.env
|
||||
docker compose -f ../../infra/woodpecker/docker-compose.yml up -d
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user