Ir al contenido

Developer reference

Esta página aún no está disponible en tu idioma.

The Artist Alley source lives at github.com/Artist-Alley-Org/artist-alley. This page is the map: top-level layout, the per-domain backend pattern, the frontend layout, the infrastructure pieces, and how a change moves from a local edit to a release.

artist-alley/
├── app/ The Go backend + the OpenAPI spec
│ ├── api/openapi.yaml HTTP contract — generates strict server + clients
│ ├── cmd/ Binary entry points (server, CLI tools)
│ ├── internal/ Per-domain Go packages (see below)
│ ├── schema.sql Postgres schema the Go side sees
│ ├── sqlc.yaml sqlc configuration
│ └── web/ Embedded SvelteKit build output (release-time only)
├── web/ The Svelte 5 frontend source
│ ├── src/
│ │ ├── routes/ SvelteKit page routes
│ │ └── lib/
│ │ ├── api/ Generated TS client from openapi.yaml
│ │ ├── components/ Shared components
│ │ ├── stores/ Svelte runes / stores
│ │ ├── i18n/ Per-locale catalogues
│ │ └── playlist/, whiteboard/, sprite/ Feature modules
│ └── package.json
├── docs/ Long-form docs (markdown) — the site pulls these
│ └── adr/ Architecture Decision Records (canonical source)
├── infra/
│ ├── docker/ Dockerfiles + compose stacks
│ ├── nginx/ Reverse-proxy config
│ └── postgres/ DB init + extension setup
├── scripts/ Dev + release shell scripts (test.sh, release.sh, etc.)
├── docker-compose.yml The dev stack — postgres + app + web + (opt) minio + workers
├── CONTRIBUTING.md High-level contribution flow
└── RELEASING.md Release cut procedure

The Go backend follows a per-domain layout under app/internal/<domain>/. Each domain owns one capability area and is self-contained.

app/internal/<domain>/
├── handler.go HTTP handlers + adapters between OpenAPI types and the domain model
├── handler_test.go Integration tests against a real Postgres
├── queries.sql sqlc-managed queries
├── queries.sql.go Generated; do not edit
└── service.go (optional) Cross-handler business logic that doesn't belong in a handler

Current domains:

DomainWhat it owns
assetsCore asset entity, lifecycle, file metadata
assettypeAsset-type lookup table
metadataField definitions, asset field values, history
collectionsCollections of assets + posts, with ACLs
postsPosts wrapping one or many assets
socialComments, likes
authSessions, login, password handling
aclsPer-row access control list checks
users, teamsIdentity surfaces
auditAudit-event ledger
cacheIn-memory cache registry with cross-domain invalidation
config, sysconfigSystem configuration surfaces
dbMigrations + low-level DB helpers
httpHTTP server bootstrap + middleware
i18nPer-locale catalogues + translation routing
jobsAsync job queue
openapiGenerated strict-server types
previewThumbnail / preview generation pipeline
setupFirst-run setup wizard
storagePluggable storage backend (fs / S3)
workflowAsset / post state machine
abr, brushpacksAdaptive bitrate + annotation toolset
loggingStructured-log shipping

Cross-domain calls go through:

  • HTTP when the domains are conceptually separate services that happen to share a binary today (and will be split later for federation).
  • Small interfaces when one domain needs a focused capability from another (e.g. audit.Recorder is passed into handlers that need to emit events).
  • The cache registry (cache.Registry) for cross-package invalidation that needs to propagate across domains in a federation-ready way.

What doesn’t happen: one domain importing another domain’s repository or query types directly. That coupling is the thing the per-domain layout exists to prevent.

web/src/
├── routes/ SvelteKit page routes — file-system-mapped URLs
│ ├── +layout.svelte Root layout
│ ├── browse/ Browse feed
│ ├── admin/ Admin shell (capability-gated)
│ ├── account/ Account preferences
│ └── ...
└── lib/
├── api/ TS client generated from openapi.yaml — do not edit
├── components/ Shared components consumed across routes
│ ├── viewers/ Universal asset viewer + per-kind view bodies
│ ├── whiteboard/ Annotation tool (Phase 1.18.B-12 / brush packs)
│ └── ...
├── stores/ Cross-route runes + Svelte stores
├── i18n/ en.json + locale catalogues
└── util/ Pure functions, no UI dependencies

Runes ($state, $derived, $effect) live in .svelte.ts files. A plain .ts file using runes errors at runtime, not compile time — see coding standards.

The API client is regenerated by npm run generate:api after every openapi.yaml change. CI does not type-check the frontend; staleness goes undetected without a local run.

infra/
├── docker/ Dockerfiles for app, web, blender worker
├── nginx/ Reverse-proxy config for production
└── postgres/ Init scripts + extension setup (pg_trgm, uuid-ossp, etc.)

The dev stack is brought up with docker compose up. Optional profiles:

  • --profile storage-s3 — runs MinIO for S3-backend testing. Daily dev uses the filesystem backend; MinIO is verification-only.
  • --profile workers — runs the Blender worker for 3D thumbnail generation.

The Go binary is the runtime. Each release ships a single artifact:

  • A multi-arch (amd64 + arm64) Docker image (ghcr.io/Artist-Alley-Org/artist-alley, mirrored to Docker Hub), keyless-signed via Sigstore.

Native binaries, .deb / .rpm packages with a systemd unit, and a Homebrew formula are a v1.0.0 target, tracked in #242.

The site at artist-alley.org is Astro Starlight and lives in a separate private repo (Artist-Alley-Org/artist-alley-site) — the site/ directory was removed from this OSS repo. At build time the site checks this OSS repo out and its sync scripts pull the doc source from docs/ and app/:

  • sync-adrs.mjsdocs/adr/*.md → augmented MDX with cross-reference cards.
  • generate-schema-docs.mjsapp/schema.sql → per-table pages + ER diagram.
  • sync-openapi.mjsapp/api/openapi.yaml → rendered API reference.
  • sync-roadmap.mjsdocs/roadmap.md → roadmap page.
  • sync-install-config.mjs — install config table from docs/install/config/aa.env.example.
  • sync-screenshots.mjs — screenshot assets for the docs.
  • fetch-github.mjs — GitHub snapshot for the engineering dashboard.

The first six run on pnpm dev (predev) and pnpm build (prebuild). fetch-github.mjs runs on demand via pnpm refresh-github. Generated content is gitignored; the source files are tracked.

Terminal window
# Bring up the stack
docker compose up -d
# Tail logs
docker compose logs -f app web
# Run a fresh Go test pass
./scripts/test.sh --go
# Run a fresh frontend type-check
docker compose exec -T web sh -c 'cd /app && npm run check'
# Run the full pass (Go + frontend)
./scripts/test.sh

After a Go binary change that isn’t picking up: docker compose up -d --build --force-recreate app. Without --force-recreate, compose can keep the old binary running.

After a frontend change that isn’t picking up: docker compose restart web. Vite HMR sometimes serves stale code.

When Postgres misbehaves: docker compose logs postgres first. Migration failures, lock issues, role wipes — the Postgres log is the diagnostic, not the app log.

feat/*devmain → tag → release.

  • Working branches merge into dev via PR (./scripts/test.sh green required).
  • dev → main happens at release boundaries via PR. Fast-forward only.
  • Release tag (v0.X.Y) on main triggers the GitHub Actions pipeline that builds the multi-arch Docker image, signs it with Sigstore, publishes to GHCR + Docker Hub, and posts the release notes. (Binaries + native packages return with #242 at v1.0.0.)
  • Self-hosted runner labelled [artist-alley] runs the heavy build steps.
  • Full procedure in RELEASING.md.

Where things you’ll commonly look for live

Section titled “Where things you’ll commonly look for live”
Looking forPath
HTTP routes and request/response shapesapp/api/openapi.yaml
The SQL that runs against Postgresapp/internal/<domain>/queries.sql
The schema you can query againstapp/schema.sql
A specific table’s documentation/developers/database/<table>/
Migration historyapp/internal/db/migrations/NNNNN_*.sql
Why we chose X over Y/adr/ — the ADR catalogue
Where a feature is on the roadmap/roadmap/
How a frontend component looksweb/src/lib/components/<area>/
A locale stringweb/src/lib/i18n/<locale>.json
Dev-stack containersdocker-compose.yml
Release procedureRELEASING.md
Contribution flowCONTRIBUTING.md + coding standards