Files
member-console/Makefile
T
cgalo5758 a5a4b9c591 Gate archives on notebook citations and add the harvest skill
A notebook's lessons survive only if they are written into a tracked
home before the decision lands, so landing a change now has three
pieces. The contract: a "Landing a change" section in MAINTAINING.md and
a fifth item in the UI definition of done. The labor: a harvest skill
that inventories the notebook, names each file's kind and routes
findings to the owning docs page, reasoning to the change's design.md,
problems to issues.md and reusable tools to a tracked home. The gate:
scripts/notebook-citations.sh, a git grep over what git would commit for
the notebook's directory shape, which make lint runs after the program's
own lint, and scripts/archive-gate.sh, which refuses an mv into the
archive or an openspec archive while the check reports hits.

The gate is one script that any harness calls with the command it is
about to run; Claude Code reaches it through a PreToolUse hook and
opencode through a plugin. Both checks live in scripts/ rather than the
lint subcommand because they are repository hygiene, not part of the
shipped program. The generated openspec-archive-change skill is not
edited; the post-archive reminder carries the harvest step instead.
2026-09-19 19:47:15 -05:00

138 lines
5.8 KiB
Makefile

# Makefile for building and pushing multi-arch Docker images
IMAGE_REPO = git.coopcloud.tech/wiki-cafe/member-console
DATE_TAG = $(shell date -u +%Y-%m-%dT%H-%MZ)
# PLATFORMS = linux/arm64,linux/amd64
PLATFORMS = linux/amd64
.PHONY: docker-push
docker-push:
docker buildx build \
--platform $(PLATFORMS) \
-t $(IMAGE_REPO):latest \
-t $(IMAGE_REPO):$(DATE_TAG) \
--push .
# Database migration targets
.PHONY: sqlc-generate spdx-headers
# The ten package directories that carry their own sqlc.yaml (seven core
# packages + three integration stores); see docs/database-management.md.
SQLC_DIRS = internal/identity \
internal/organization \
internal/billing \
internal/entitlements \
internal/integration \
internal/domains \
internal/instance \
internal/integrations/fedwiki/store \
internal/integrations/stripe/store \
internal/integrations/discourse/store
sqlc-generate:
@for dir in $(SQLC_DIRS); do \
echo "sqlc generate: $$dir"; \
(cd $$dir && sqlc generate) || exit 1; \
done
@./scripts/spdx-headers.sh $(SQLC_DIRS)
# sqlc rewrites its output with no license header, so every regeneration drops
# the SPDX identifiers that sqlc-generate restores above. This target stamps
# the whole tree, for files added outside a generator.
spdx-headers:
@./scripts/spdx-headers.sh
# Build the application
.PHONY: build
build:
go build -o member-console .
# Run the test suite against pristine test databases. reset-test-db.sh drops,
# recreates, and migrates the tests' own databases (never the app's), so the
# suite starts from migrations only and a running app cannot perturb it.
# Requires the stack up: cd test && ./bootstrap-stack.sh && docker compose up -d.
#
# -count=1 because Go's test cache keys on code and env, not database state:
# after a reset, a cached "ok" would be reporting on a database that no
# longer exists.
#
# -p 1 because several packages commit rows that other packages read: the
# org-type-change suites set and restore personal.default_plan_ladder_id
# while internal/provisioning asserts it is unset; the discourse operator and
# webhook suites commit group mappings that the reconcile suite's fake forum
# has never heard of. Serializing packages closes that whole class. It is not
# a stand-in for the separate e2e database — serialization orders commits, it
# does not undo them — the two fixes cover different vectors.
# Static UI integrity checks (M7f.1 + page-anatomy): dead routes and targets,
# the page-anatomy rules with their shrinking allowlist, screen coverage.
# Runs first in `make test`; there is no CI configuration in this repository
# yet, so this is the gate.
.PHONY: lint
lint:
@go run . lint
@./scripts/notebook-citations.sh
# Repository hygiene, not the program: no tracked text names a path under
# status/explorations/, the local notebook git ignores (status/MAINTAINING.md,
# "Landing a change"). lint runs it too; this target runs it alone.
.PHONY: notebook-citations
notebook-citations:
@./scripts/notebook-citations.sh
# Screen capture utility (page-anatomy, spec ui-quality-gate): resets the
# application database to the demo state (test/reset-app-db.sh, so every
# capture comes from the same data), then captures every route in
# test/e2e/screens/manifest.go at desktop and phone width, writes one contact
# sheet per surface under test/screens/out/, and compares each screen with
# test/screens/baseline/. Needs the stack in test/.env up. `screens-accept`
# makes the current output the baseline. Both directories are gitignored.
.PHONY: screens
screens:
@cd test && ./reset-app-db.sh
@SCREENS=1 go test ./test/e2e/screens/ -count=1 -run TestScreens -v 2>&1 | grep -v '^=== RUN\|^--- PASS\|^PASS\|^ok ' || true
@test -f test/screens/out/changes.txt && { echo "changed or new screens:"; cat test/screens/out/changes.txt; } || true
.PHONY: screens-accept
screens-accept:
@rm -rf test/screens/baseline && cp -r test/screens/out test/screens/baseline && echo "baseline accepted from test/screens/out"
.PHONY: test
test: lint
@cd test && ./reset-test-db.sh && set -a && . ./.env && set +a && cd .. && go test -count=1 -p 1 ./...
# Respin the test stack from scratch: teardown (drops volumes), regenerate
# per-worktree ports/secrets, bring compose back up. The app and demo seed
# stay manual because migrations run at app boot (see test/AGENTS.md,
# "Browser walkthroughs (e2e) and stack age"). Suite freshness does not need
# this — `make test` resets the test databases on its own; respin when the
# *app* database or another service's state needs clearing.
#
# Composes the core stack. Teardown drops test/.env, so a composition carries
# over only if you pass it back in:
# make stack-fresh COMPOSE_PROFILES=fedwiki,discourse
.PHONY: stack-fresh
stack-fresh:
cd test && ./teardown-stack.sh && COMPOSE_PROFILES="$(COMPOSE_PROFILES)" ./bootstrap-stack.sh && docker compose up -d
@echo ""
@echo "Stack is fresh. For a full-exercise browser-walkthrough run:"
@echo " 1. cd test && set -a && . ./.env && set +a && go run .. start --config mc-config.yaml # boots + migrates"
@echo " 2. ./test/seed-demo.sh # walkthrough subjects (demo catalog + one active grant)"
@echo " 3. go test ./test/e2e/operator-walkthroughs/ -count=1"
@echo ""
@echo "Integration walkthroughs skip unless their compose profile is on AND"
@echo "the matching MC_* block in test/.env is uncommented (see test/AGENTS.md)."
@echo ""
@echo "The Go suite needs none of that: make test"
# Lint: ensure no handler bypasses SafeTemplates by writing directly to ResponseWriter.
# All template rendering must go through h.Templates.Render() — see internal/server/render.go.
.PHONY: lint-templates
lint-templates:
@if grep -rn '\.ExecuteTemplate(w,' internal/server/; then \
echo "ERROR: Direct ExecuteTemplate on ResponseWriter found. Use h.Templates.Render() instead."; \
exit 1; \
else \
echo "OK: No direct ExecuteTemplate on ResponseWriter detected."; \
fi