Repository navigation
fix: preserve legacy profile and interview data compatibility - #89
Merged
Merged
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The core profile type remains unsound for nullable topics, and the OpenAPI 3.1 document uses an unsupported nullable representation.
2 open findings
What changed in this PR
Adds compatibility for legacy nullable profile topics and historical interview-question formats without rewriting persisted data.
Changes:
- Normalizes legacy SQLite question metadata on reads.
- Allows nullable profile topics across contracts and generated API types.
- Adds end-to-end regression coverage for legacy data.
| File | Description |
|---|---|
tests-ts/contracts/real-service-harness.ts |
Supports custom profile repositories and stored-question inspection. |
tests-ts/contracts/legacy-data-compatibility.test.ts |
Tests legacy profile and interview compatibility. |
packages/db/src/interview-repositories.ts |
Normalizes legacy questions during reads. |
packages/contracts/src/profile-responses.ts |
Accepts nullable profile topics. |
packages/contracts/openapi.json |
Updates generated profile schemas. |
frontend/src/api/schema.d.ts |
Exposes nullable topics to frontend consumers. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+13
to
+14
| // The legacy recording fallback saved null for observations without a topic. | ||
| topic: z.string().nullish(), first_seen: z.string().optional(), last_seen: z.string().optional(), times_seen: z.number().optional(), |
Comment on lines
+1118
to
+1119
| "type": "string", | ||
| "nullable": true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Historical recordings can store null observation topics, and Python-era drills can store null optional question metadata or numeric string difficulty. These values caused profile, due-review, review, resume, and topic-history reads to return 500 after response validation was tightened.
Accept null profile topics and normalize the known legacy question representations when reading SQLite, preserving provider extensions and the original stored data. New model output retains its strict validation. Update OpenAPI and generated frontend types.
Validation: 539 backend/contract tests pass; frontend tests, Bun/Node/frontend type checks, architecture boundaries, lint, API and web builds pass. Seven regression tests exercise real profile files, SQLite and HTTP, verify unchanged persisted data, and check that malformed new questions are rejected before writes. Four regression cases failed before the fix.