Files
feedBack/.dockerignore
T
byrongamatosandClaude Opus 4.8 73a654f293 feat(server): add appstate.py, the router seam (R3)
Routes moving out of server.py need `meta_db` and friends, but must not
`import server` -- that goes circular the moment server imports them back.
server.py keeps CONSTRUCTING its singletons and now injects them once via
`appstate.configure(...)`; routers read them back as module attributes at call
time (`import appstate; appstate.meta_db`). The Python analogue of the frontend
refactor's `configureX({...})` seams and of the plugin `setup(app, context)`
contract: dependencies flow one way, server -> routers -> appstate.

Two properties are load-bearing, both pinned by tests/test_appstate.py:

1. `import appstate` constructs nothing and touches no disk. This is why the
   ~49 test fixtures that `sys.modules.pop("server")` + re-import (to rebuild
   meta_db under a patched CONFIG_DIR) keep working UNTOUCHED. A singleton
   owned by appstate would survive that pop and go stale -- verified.
2. Reads must be late-bound. `from appstate import meta_db` freezes the binding
   and defeats both a later configure() and monkeypatch.setattr -- the same
   read-only-binding trap as ES imports.

configure() raises on an unknown slot instead of silently creating a global
nothing reads, and the suite asserts server ACTUALLY calls it. Negative-checked:
dropping the configure() call fails exactly the two wiring tests while the other
five stay green -- those five are the false-green a seam test must not be.

The new suite imports server through an `isolated_server` fixture that patches
CONFIG_DIR to tmp_path and closes both DB connections on teardown. An unguarded
`import server` constructs MetadataDB + AudioEffectsMappingDB under the real
`~/.local/share/feedback` (reproduced: running the file alone created
web_library.db + audio_effects.db there). The full suite now leaves the real
config dir untouched.

Packaging: `COPY appstate.py /app/` plus a .dockerignore allowlist entry. That
file opens with a blanket `*` exclusion, so root-level Python must be re-allowed
explicitly -- without it the image build fails on the COPY. Verified against the
real docker daemon (build context reaches /app/appstate.py). docker-compose.yml
gains the dev bind-mount; docker-compose.nas.yml runs the baked image, so the
COPY covers it. `routers/` will need the same two entries when it lands.

Verified: pyflakes clean; pytest 2348 passed (2341 + 7 new); eslint 0 errors;
boot smoke serves /api/version, /api/library, /api/audio-effects/mappings, and
all three migrated plugins' src/ graphs, with `appstate.meta_db is server.meta_db`
asserted against the live import.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 14:49:54 +02:00

84 lines
2.1 KiB
Plaintext

*
!.dockerignore
!Dockerfile
!dockerfile
!requirements.txt
!server.py
# The router seam server.py injects its singletons into (R3). Root-level Python
# that ships in the image must be re-allowed explicitly — this file starts with
# a blanket `*` exclusion. `routers/` needs the same treatment when it lands.
!appstate.py
!main.py
!VERSION
!tailwind.config.js
!lib/
!lib/**
# Mirror the static/* policy from .gitignore: ship the static tree, but not
# the cached audio/art artifacts a developer's runtime would generate
# (static/*.ogg, *.mp3, *.wav, art/, audio_*/). Those bloat the image and
# make builds non-reproducible across machines.
!static/
!static/**
static/*.ogg
static/*.mp3
static/*.wav
static/art/
static/audio_*/
static/sloppak_cache/
# note-detection tuning flow auto-writes WAVs and JSONL captures here.
# Not in .gitignore yet — see docs/note-detect-tuning.md — but still a
# generated-at-runtime directory that shouldn't bake into the image.
static/note_detect_recordings/
# All in-tree core plugins ship in the image. Each plugin directory must be
# explicitly re-allowed after the blanket `plugins/*/` exclusion below.
!plugins/
plugins/*/
!plugins/__init__.py
!plugins/app_tour_library/
!plugins/app_tour_library/**
!plugins/app_tour_settings/
!plugins/app_tour_settings/**
!plugins/capability_inspector/
!plugins/capability_inspector/**
!plugins/highway_3d/
!plugins/highway_3d/**
!plugins/minigames/
!plugins/minigames/**
!plugins/tuner/
!plugins/tuner/**
!data/
!data/**
# Ship only the built-in diagnostic sloppak artifacts (seeded into
# DLC_DIR/diagnostics-builtin/ at scan time). The builder script + README
# under docs/diagnostics/ are dev-only and stay out of the image.
!docs/
docs/*/
!docs/diagnostics/
docs/diagnostics/*
!docs/diagnostics/*.sloppak
# Exclude common developer artifacts even inside the whitelisted trees so a
# venv / cache / build output never gets baked into the image.
**/__pycache__/
**/*.pyc
**/.pytest_cache/
**/.mypy_cache/
**/.ruff_cache/
**/node_modules/
**/.venv/
**/venv/
**/.env
# (the Dockerfile builder stage rebuilds from source). A contributor
# into the build context.
**/bin/
**/obj/
**/.env.*
**/.DS_Store