Skip to content

feat: add course lookup and moderated ratings#62

Open
SebastianBoehler wants to merge 3 commits into
mainfrom
agent/61-feedback
Open

feat: add course lookup and moderated ratings#62
SebastianBoehler wants to merge 3 commits into
mainfrom
agent/61-feedback

Conversation

@SebastianBoehler

@SebastianBoehler SebastianBoehler commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • pivot the feedback feature from rating the StudyOS agent to searching and rating university courses
  • add a dedicated Course ratings screen with StudyPlanner catalog lookup and local “My courses” search shortcuts
  • add per-course stars, optional moderated comments, aggregate/public comment display, update/delete/report flows, and explicit moderation states
  • refactor the FastAPI + SQLite service around registered normalized course identities, with a bounded/rate-limited StudyPlanner catalog proxy
  • retain pseudonymous installation ownership, moderation/report queues, audit records, hardened Compose defaults, backup verification, and deployment/privacy guidance

Course lookup and identity

Flutter calls POST /v1/courses/search on the ratings service. The service forwards only the search text to the public StudyPlanner catalog, validates and bounds the response, caches up to 64 searches for five minutes, and returns a server-issued rating ID based on the normalized course number. Only registered catalog results can receive ratings; the database enforces one rating per installation/course.

Ratings intentionally aggregate the same course number across semesters. They are pseudonymous community ratings, not verified enrollment reviews.

Security and privacy

  • ALMA credentials, cookies, profile data, timetables, and enrollment lists remain local
  • choosing a “My courses” shortcut sends only that course title as a public catalog search; lookup uses POST to avoid URL history/access-log leakage
  • installation tokens are random 256-bit bearer credentials and only SHA-256 digests are stored
  • catalog lookup has per-peer/global limits, a 256 KB upstream response cap, typed/length-bounded fields, and a true 64-entry LRU cache
  • arbitrary client-created course buckets are rejected; feedback references registered courses through a foreign key
  • comments remain pending until published; moderator credentials stay server-side and actions are audited
  • no third-party semantic moderation or usage-based moderation billing is introduced

Validation

  • ruff format --check feedback_service
  • ruff check feedback_service
  • pytest -q feedback_service/tests (18 passed)
  • live StudyPlanner catalog proxy smoke test
  • dart format lib test
  • dart analyze (no issues)
  • GitHub Actions Flutter suite (125 passed)
  • git diff --check
  • independent StudyOS quality/security review: no actionable Medium/High findings

The ARM runtime cannot execute Flutter's x64 widget-test engine, so GitHub Actions provides the full Flutter/widget verification. Docker is not installed in the runtime, so the Compose launch was not executed locally.

Deployment follow-up

Before public launch, choose the HTTPS host, exact CORS origins, moderation owner/response expectations, privacy notice, retention periods, backup destination/expiry, and secret rotation process. Schema v1 belonged to the abandoned agent/service-rating prototype and is deliberately refused rather than relabeled as course feedback; prerelease volumes must be backed up and recreated.

Closes #61

@SebastianBoehler

Copy link
Copy Markdown
Contributor Author

The direction is useful: this removes the release-embedded GitHub write token and gives ratings/comments explicit ownership, moderation, reporting, and deletion contracts. I found two reliability issues worth fixing before this lands:

  1. Medium — backup verification accepts an empty/wrong database (feedback_service/backup.py:17-34). sqlite3.connect(source) creates a missing source path, and both create and verify only run PRAGMA integrity_check. I reproduced a typoed source path producing a successful backup with user_version=0 and zero tables. That can make an operator believe recovery is covered when no StudyOS data was backed up. Please open the source read-only and have both paths assert the expected schema version/required tables; add tests for a missing source and an empty/unrelated SQLite file.

  2. Medium — public-feed failures can corrupt the owned-feedback UX (flutter_app/lib/src/widgets/feedback_settings_card.dart:49-60, :73-91, :119-137). Initial load awaits the public GET before loadOwn(), so a public-read failure leaves an empty editor enabled even when owned feedback exists; submitting then overwrites it. After a successful PUT/DELETE, a failed public refresh also prevents applying the successful mutation locally, leaving stale controls and a misleading failure. Please load/apply owned feedback independently, commit local state as soon as the mutation succeeds, and refresh the aggregate as a separate best-effort operation. Widget tests where public GET fails but mine/PUT/DELETE succeeds would pin this down.

Useful launch review angles after those fixes: verify the deployed reverse-proxy trust topology so installation issuance is keyed by the real client rather than one shared Docker peer, and explicitly document the deletion/recovery path when secure storage is reset and an installation loses ownership of a published comment. The validation jobs and the Linux/Web builds are green at review time; the remaining platform artifact builds were still running.

Concrete next step: fix the two cases above, add the focused regression tests, then rerun the suite and finish the proxy/identity launch decisions already called out in the PR description. These are change-request-level reliability issues; the overall architecture looks reasonable.

@SebastianBoehler SebastianBoehler changed the title feat: add moderated service ratings and comments feat: add course lookup and moderated ratings Jul 17, 2026
@SebastianBoehler
SebastianBoehler marked this pull request as ready for review July 17, 2026 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add course lookup, ratings, and moderated comments

1 participant