Local dev setup; fix mirror volume ownership and a test footgun

Adds docker-compose.override.yml (local-only: publishes the server on
127.0.0.1:8080 and Postgres on 127.0.0.1:55432, crawls on demand) and
docs/LOCAL.md covering the stack, Claude Code registration over both
transports, the CLI, and the test suites.

Two bugs that only running the real container could find:

The mirror volume was root-owned while the container runs as node, so
every file write failed with EACCES. Docker initialises a named volume
from the image directory including its ownership, so the fix is to
create /data/mirror owned by node in the image. This was easy to miss
because the indexer records a per-file failure rather than crashing —
the crawl "succeeded" with 4 skipped. Earlier direct-node testing missed
it entirely by writing to a scratch dir owned by the developer.

The store tests TRUNCATE, and pointing TEST_DATABASE_URL at the dev
database put their fixtures into real data. They now refuse any database
whose name does not contain "test".

Verified against the rebuilt container: 4 files mirrored, image-only PDF
detection firing in the real pipeline, both transports showing
✔ Connected in `claude mcp list`, and a whoami tool call driven end to
end through `claude -p`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-12 21:57:35 +02:00
parent 359c46afad
commit e6f2258df9
6 changed files with 166 additions and 7 deletions

View File

@@ -64,8 +64,9 @@ npm run build
npm run probe # verifies the token and API against the live instance
```
Then either deploy it as a remote connector, or point Claude Code at
`dist/bin/stdio.js`. Both paths are in [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md).
To try it on your own machine — Docker stack, Claude Code, and the CLI — follow
[docs/LOCAL.md](docs/LOCAL.md). To put it on a Pi behind Caddy, see
[docs/DEPLOYMENT.md](docs/DEPLOYMENT.md).
Getting `TSC_JWT_COOKIE` takes four clicks in DevTools and then lasts 30 days —
provided you close the Schulportal window afterwards. See