The Trap
Traceo’s repository factory (traceo_mcp_server/repositories/factory.py) selects the storage backend based on two conditions: (1) DATABASE_URL is set, and (2) psycopg3 is importable. If either condition fails, it silently falls back to file-based storage with only a warning log. This means:
- Running
python scripts/seed_requirements.pylocally without psycopg3 installed creates 80 YAML files on disk - The script reports “Seeded 80 requirements” with zero errors
- The Railway Postgres database remains completely empty
- The dashboard shows all zeros
The Fix
For seeding scripts that target production: bypass the factory entirely and connect to Postgres directly viapsycopg3. The convert_and_seed.py script does this correctly — it opens its own AsyncConnectionPool with an explicit --database-url parameter instead of going through RequirementService. The key lesson: seeding scripts should never rely on the application’s storage abstraction layer when targeting a specific backend.