Skip to content

Replace flat-file student profiles with a real, concurrency-safe datastore #2

Description

@llinsss

Problem

agent/profiler.py does a read-JSON → mutate-in-memory → write-JSON cycle with no locking (load_profile / save_profile). Two concurrent /attempt requests for the same student (very plausible — a game client retrying a timed-out request, or multiple devices) can race: the second write silently clobbers the first's update, dropping SM-2 review state.

Scope

  • Introduce a real datastore (SQLite is acceptable for this stage, Postgres if you want to go further) with a schema covering: students, per-word learning state, phonics struggles, theme preferences, session history.
  • Make attempt-recording atomic per student (row-level lock, transaction, or optimistic concurrency with retry).
  • Write a migration path: a one-time script that imports existing data/student_profiles/*.json into the new store.
  • Preserve the existing function signatures in agent/profiler.py where reasonable so recommender.py and dashboard/report.py don't need rewrites — or update all callers if the interface has to change, and say why in the PR.

Acceptance criteria

  • A concurrency test: fire N parallel record_attempt calls for the same student/word and assert the final attempts count equals N (this test should fail against the current implementation and pass after the fix).
  • Migration script converts a sample of existing JSON profiles without data loss (test against fixtures).
  • All existing tests pass against the new storage layer.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    architectureStructural/system design changesdata-integrityData correctness/consistency

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions