rdev/scripts/generate-sdk.sh
jordan 002c32aedb feat: add album generation system to skeleton
Adds anchor-based image album generation across docs, skeleton, and rendered
full-monorepo. One subject description + one anchor image + N directed shots,
covering personas, products, characters, and brand assets out of the box.

## What ships

**Skeleton packages:**
- pkg/album/types.go — Album, Shot, ShotStatus, ShotTemplate, AlbumUpdater
- pkg/album/templates.go — PortraitSession, ProductShoot, CharacterSheet built-ins
- pkg/album/handler.go — AnchorHandler + ShotHandler queue job handlers
- packages/realtime/src/useAlbumGeneration.ts — SSE hook owning all album state
- packages/ui/src/components/AlbumGrid.tsx — responsive shot grid with shimmer
- packages/ui/src/components/ShotCard.tsx — pending/generating/complete/failed states
- packages/ui/src/components/AnchorPreview.tsx — anchor CTA + image with controls

**Component service template:**
- internal/port/album.go — AlbumRepository interface
- internal/adapter/memory/album.go — in-memory repo for standalone dev
- internal/service/album.go — create, list, get, generateAnchor, generateAllShots
- internal/api/handlers/album.go — HTTP handlers (CRUD + 202 generation endpoints)
- Routes: GET/POST /albums, GET/DELETE /albums/{id}, POST /albums/{id}/anchor,
  POST/DELETE /albums/{id}/shots, POST /albums/{id}/shots/{index}

**Documentation:**
- .claude/guides/album.md — full guide with API, SSE events, frontend usage

**Key architecture decisions:**
- Anchor bytes never stored in queue payload — workers fetch AnchorURL at runtime
- Generation order enforced: POST /shots returns 422 if no anchor exists
- All album SSE events on existing user:<userId> channel (no new channel)
- AlbumUpdater interface lets job handlers update repo from inside queue workers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 23:57:21 -07:00

50 lines
1.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# generate-sdk.sh — Generate the @orchard9/rdev-sdk TypeScript SDK from the embedded OpenAPI spec.
# No server, DB, or K8s needed. The spec is exported directly from the Go binary.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT="$SCRIPT_DIR/.."
SDK_DIR="$ROOT/sdk"
# 1. Check speakeasy is installed
if ! command -v speakeasy &>/dev/null; then
echo "speakeasy CLI not found. Installing..."
if command -v brew &>/dev/null; then
brew install speakeasy-api/speakeasy/speakeasy
else
# Install to ~/.local/bin (no sudo needed)
mkdir -p "$HOME/.local/bin"
curl -fsSL https://raw.githubusercontent.com/speakeasy-api/speakeasy/main/install.sh \
| INSTALL_DIR="$HOME/.local/bin" sh
export PATH="$HOME/.local/bin:$PATH"
fi
fi
# 2. Export the OpenAPI spec (no server needed — pure Go, no external deps)
echo "Exporting OpenAPI spec..."
go run "$ROOT/cmd/rdev-api" --export-openapi > "$SDK_DIR/openapi.json"
echo " -> $SDK_DIR/openapi.json"
# 3. Validate the spec
echo "Validating spec..."
speakeasy validate openapi -s "$SDK_DIR/openapi.json"
# 4. Generate the TypeScript SDK
echo "Generating TypeScript SDK..."
speakeasy generate sdk \
--schema "$SDK_DIR/openapi.json" \
--lang typescript \
--out "$SDK_DIR/typescript" \
--config "$SDK_DIR/.speakeasy/gen.yaml"
# 5. Install dependencies and build
echo "Building SDK..."
cd "$SDK_DIR/typescript"
npm install
npm run build
echo ""
echo "Done! SDK generated at sdk/typescript/"
echo "Test with: cd sdk/typescript && npm pack --dry-run"