PR7b — feat(marketplace): preview attempt (Phase 2)#8511
Conversation
562e8a5 to
d9d825a
Compare
| render partial: 'jobs/submitted', locals: { job: job } | ||
| end | ||
|
|
||
| def generate_live_feedback # rubocop:disable Metrics/AbcSize, Metrics/MethodLength |
There was a problem hiding this comment.
[Correctable] Lint/RedundantCopDisableDirective: Unnecessary disabling of Metrics/MethodLength.
| # frozen_string_literal: true | ||
| json.submission do | ||
| json.partial! 'course/assessment/submission/submissions/attempt', attempt: preview_attempt, assessment: assessment, | ||
| can_grade: can_grade, can_update: can_update |
There was a problem hiding this comment.
[Correctable] Layout/HashAlignment: Align the keys of a hash literal if they span more than one line.
| json.partial! 'course/assessment/submission/submissions/answers', submission: @submission, answers: answers | ||
| json.partial! 'course/assessment/submission/submissions/topics', submission: @submission, | ||
| submission_questions: submission_questions, | ||
| can_grade: can_grade |
There was a problem hiding this comment.
[Correctable] Layout/HashAlignment: Align the keys of a hash literal if they span more than one line.
| answers: answers | ||
| json.partial! 'course/assessment/submission/submissions/answers', submission: @submission, answers: answers | ||
| json.partial! 'course/assessment/submission/submissions/topics', submission: @submission, | ||
| submission_questions: submission_questions, |
There was a problem hiding this comment.
[Correctable] Layout/HashAlignment: Align the keys of a hash literal if they span more than one line.
| json.partial! 'course/assessment/submission/submissions/questions', assessment: @assessment, submission: @submission, | ||
| can_grade: can_grade, | ||
| submission_questions: submission_questions, | ||
| answers: answers |
There was a problem hiding this comment.
[Correctable] Layout/HashAlignment: Align the keys of a hash literal if they span more than one line.
|
|
||
| json.partial! 'course/assessment/submission/submissions/questions', assessment: @assessment, submission: @submission, | ||
| can_grade: can_grade, | ||
| submission_questions: submission_questions, |
There was a problem hiding this comment.
[Correctable] Layout/HashAlignment: Align the keys of a hash literal if they span more than one line.
| where(question: @submission.questions).includes({ discussion_topic: :posts }) | ||
|
|
||
| json.partial! 'course/assessment/submission/submissions/questions', assessment: @assessment, submission: @submission, | ||
| can_grade: can_grade, |
There was a problem hiding this comment.
[Correctable] Layout/HashAlignment: Align the keys of a hash literal if they span more than one line.
68546f0 to
b1b31c1
Compare
d9d825a to
f850512
Compare
b1b31c1 to
7afa40f
Compare
f850512 to
3900460
Compare
7afa40f to
15b1eee
Compare
3900460 to
46fb69c
Compare
15b1eee to
fbed966
Compare
46fb69c to
4c04c36
Compare
fbed966 to
f35dd0c
Compare
4c04c36 to
bec2ee1
Compare
f35dd0c to
eb015b3
Compare
bec2ee1 to
a466080
Compare
Design-C marketplace preview groundwork, no schema change: - Attempt#preview? (true when the attempt has no Submission extension row) — the single source of truth for preview-only branching. - Attempt#reset_attempt! — destroys answers, returns to attempting, rebuilds answers (backs the preview 'Reset attempt' action). - Course::Assessment::PreviewAttemptReapingJob (TTL 7d) + daily schedule — deletes only extension-less previews past TTL; real submissions never reaped (mutation-verified). - validate_unique_submission left unchanged: the DB unique index already forbids two attempts per (assessment, creator); normal preview creation hits no prior attempt, and the unscoped rule yields the friendly collision error create-or-reuse relies on. Plan: docs/superpowers/plans/2026-07-23-marketplace-preview-increment-a-lifecycle.md
…review serving Increment B foundation: an Attempt must stand in as @submission when serving a marketplace preview, but the shared submission jbuilders call course_user/current_points_awarded/ experience_points_record/publisher on the served object — the EXP/course-coupled slice the extension owns. Delegate those to the (optional) extension with allow_nil, so a preview (no extension) returns nil and a real submission returns the extension's values. Exercised only by previews; real submissions serve via the extension directly. Interface set audited against app/views/course/assessment/submission/submissions/*.jbuilder.
…, jbuilders Increment B: PreviewAttemptsController serves marketplace preview attempts by reusing the platform submission edit/update pipeline, treating a bare Course::Assessment::Attempt (no Submission extension) as @submission. Covers create/edit/update/auto_grade/reset (core routes); live-feedback/scribing actions are authored here (single-file authoring) but wired up by a later task. PreviewUpdateService subclasses Submission::UpdateService to drop the EXP-only draft_points_awarded/points_awarded params an Attempt has no columns for, and to build SubmissionQuestion rows against the Attempt directly (the parent assumes a Submission extension with its own #attempt association). Also covers a repo-wide deferred-workflow-state-persistence gotcha in the new spec: a bare `attempt.finalise!` only transitions workflow_state in memory (lib/extensions/ deferred_workflow_state_persistence) and needs an explicit save to be visible to a subsequent reload/re-find, same as Submission#finalise! already does internally.
…nal call; scope preview loading to previews
…ubmission -> gradable.submission) The dual-typed param (Attempt in production, Submission in legacy specs) read as submission.submission when resolving the extension. Rename to `gradable` so the extension access reads gradable.submission. Behavior-preserving.
The preview reuses the submission edit UI, whose per-answer autosave and per-question submit hit dedicated answer endpoints. Add the preview equivalents so saving/submitting an answer in a preview no longer 404s on the platform /assessments/:aid/submissions/... route. - New shallow routes + #save_draft / #submit_answer actions on the preview attempts controller, reusing the platform answer write path (UpdateAnswerConcern) and the extracted SubmitAnswerConcern. - Extract the submit auto-grade helpers from AnswersController into Course::Assessment::Answer::SubmitAnswerConcern (renamed auto_grade -> auto_grade_answer to avoid colliding with the preview controller's whole-attempt #auto_grade action). - Grant :save_draft/:submit_answer on a preview-owned Attempt.
eb015b3 to
e8b9992
Compare
a466080 to
4c28286
Compare
PR7b — Marketplace preview attempt (Phase 2)
Stacked on #8510 (
pr7a-attempt-base-record). Adds the marketplace "Try it out" preview feature on the base-record foundation from PR7a.A preview is a bare
Attemptwith noSubmissionextension row (Attempt.previews == where.missing(:submission)) — nocourse_user, no EXP, throwaway. Eligible users rehearse a published assessment interactively (answer → submit → auto-grade → view-as-grader) without creating a real submission, joining a course, or earning EXP.What's in it
Attempt#preview?,#reset_attempt!, TTL reaping job (Increment A)Marketplace::PreviewAttemptsController(create-or-reuse keyed onAttempt.previews; edit / update / auto_grade / reset + live-feedback / scribing) reusing the platform submission pipeline with theAttemptstanding in as@submission;PreviewUpdateService, courselessPreviewAutoGradingService, preview jbuilders (+ shared_attemptpartial extracted from_submission)preview? && creator_id == user.idabilities; published-listing gate on create (:preview_in_marketplace);(assessment, creator)collision → clean 409Notable fixes surfaced during this work
Attempt(points_awarded=lives only on the extension) — affected real and preview autograded finalise; now extension-aware + preview-safe (Submission::AutoGradingService).Testing
All backend specs green (consolidated sweep: 92 examples, 0 failures, 11 pending). Every task independently reviewed; final whole-branch review passed after the two hardening fixes above.
Not yet included (next increment): the frontend (~10 ported files) and the launch→answer→grade feature/Capybara specs.