Files
zeekayandHanzo Dev 50aa91efd4 Hanzo Social — publish to every account an org owns
A social publishing surface on @hanzo/gui + @hanzo/ui, written against the
platform's own /v1/social and /v1/integration. Six screens: the org roll-up,
a composer, the posts in every state, a month calendar, the networks with
their consent and their handles, and the delivery record.

Two facts shape it. A post carries one channel, so the composer stores one
post per network — which is also what makes writing separately for a single
network free, since it is a different content on that row. Media is a list of
addresses, so a video is ordinary content rather than a second kind of post,
and each network's own rules are checked before the post is stored rather
than discovered at a publish hours later.

State is drawn in luminance on a palette with no hues, and the inversion is
spent once per screen on the thing a person has to act on. Refusals are the
platform's own sentence, read off the RFC 7807 detail the SDK's extractor
drops — a 503 that names the missing credentials is the whole of what anyone
can act on.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-15 06:40:41 -07:00

41 lines
1.7 KiB
Docker

# syntax=docker/dockerfile:1.7
# Hanzo Social — the Vite SPA built once, served by hanzoai/spa.
FROM node:24-alpine AS build
WORKDIR /build
ENV CI=true PNPM_HOME=/pnpm PATH=$PNPM_HOME:$PATH
RUN corepack enable && corepack prepare [email protected] --activate
# Manifests first so a source edit re-runs the build and not the resolve.
#
# pnpm-workspace.yaml is REQUIRED even though this repo has no workspace
# members: every dependency is `catalog:`, and the catalog lives in that file.
# It also carries the overrides that keep ONE copy of the gui runtime — two are
# two theme contexts, and every themed component then throws.
#
# FROZEN, and the lockfile ships. A resolver left free to drift builds a tree
# nobody ran; frozen, the image gets the tree the gate passed against.
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
RUN pnpm install --frozen-lockfile
COPY tsconfig.json vite.config.ts index.html ./
COPY src src
# `pnpm build` is `tsc --noEmit` && `vite build`, so the typecheck is part of
# the image.
#
# `&&`, not `;`: with `;` the RUN carries the status of the LAST command and a
# failed build would be masked. A vite build that emits nothing still exits 0,
# which is what the file tests are for.
RUN pnpm build \
&& [ -s dist/index.html ] \
&& [ -d dist/assets ]
# hanzoai/spa, not hanzoai/static, and not a webserver of our own: this is a
# client-routed SPA, so it needs index.html served for every path.
# hanzoai/static defaults to `Content-Security-Policy: default-src 'none'`,
# which blocks the bundle the page loads and leaves a blank screen.
# Defaults: PORT=3000, ROOT=/public.
FROM ghcr.io/hanzoai/spa:1.4.11
COPY --from=build /build/dist /public
EXPOSE 3000