various frq related bug fixes - #393
Merged
Famousmaster206 merged 3 commits intoSep 3, 2026
Merged
Conversation
…al ones Five issues reported against the FRQ feature (AP-Students#357). The editor had no way out. It renders a fixed full-screen layout with no navbar and held no links at all, so once opened the only exit was the browser's back button. It now carries the same back links the MCQ test editor has — from the same component, rather than a second copy of the pattern — including the Blocker that confirms before discarding unsaved work. The header moved off equal thirds, which no longer fit and had been truncating the points total. FRQs could not be deleted, only hidden. The tests list has had a delete control all along; FRQs now have the matching one. It writes through immediately rather than deferring to Save, because each FRQ is its own document rather than an array inside the unit doc. Bullets appeared to do nothing. The markup was always correct — preflight resets list-style and padding on ul/ol, so the markers were never drawn. The classes the renderer already applied are now shared constants used by both editable surfaces too, so the three cannot drift apart again. The omega button inserted a literal omega. It is the standard icon for a character palette, so it now opens one: 99 characters in six groups, with the caret saved and restored across the popover taking focus. FRQ authoring boxes hid their own syntax. They are the same component the MCQ boxes use, but passing a placeholder overrode the hint documenting LaTeX, code fences and image placeholders, so authors had no sign those were supported. The hint is now composed onto the caller's lead-in. Submissions were invisible to staff, and could not be self-graded. The dashboard panel was nested inside an admin-only block; members and graders now see it, and members can grade. Submitting offers a choice between the staff queue and grading it yourself. Self-assessments are stored in their own collection rather than alongside official results. Anyone may score their own attempt however they like, so nothing stored there carries a grader's authority: graded-frqs stays unwritable by students, no query for official results has to filter self-grades back out, and the feedback page labels one when it shows it. Grading your own work counts as a self-assessment whatever access you hold, so a member cannot file their own attempt as an official grade. Rules were verified by compiling them against the emulator's securityRules endpoint (200, no warnings), with a deliberately broken copy as a control. That also turned up isGraderOrAdmin, dead since graders moved onto isGraderOrMemberOrAdmin, which is removed. They still need deploying. Claude-Session: https://claude.ai/code/session_01UC5oRPG1AvmXKhDPmYMvfh
firestore.indexes.json still described indexes for gradableFrqSubmissions
and gradedFrqSubmissions, collection names the code left behind when the
FRQ queue moved to ungraded-frqs / graded-frqs / self-graded-frqs. One of
them listed a single field, which Firestore rejects through the composite
index API — "this index is not necessary" — and that 400 aborted
`npm run deploy:rules` before the rules could go out.
The only query these collections carry is orderBy("submittedAt", "desc")
on ungraded-frqs, which a single-field index serves automatically, so the
composite list is emptied rather than corrected. A filtered query added
later will prompt for the exact index it needs.
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
It changes grading flows and Firestore security rules/authorization semantics, which warrants careful human verification of access boundaries and data integrity.
Pull request overview
This PR addresses multiple FRQ authoring, submission, and grading workflow bugs by aligning FRQ tooling with existing MCQ editor patterns, fixing rich-text list rendering, adding a special-character palette, and introducing a dedicated self-assessment storage path (self-graded-frqs) with corresponding UI and security-rule updates.
Changes:
- Add self-grading flow that writes official grades to
graded-frqsand self-assessments toself-graded-frqs, updating UI flows and Firestore rules accordingly. - Fix FRQ editor/navigation usability (shared back links + unsaved-changes blocking) and enable deleting FRQ templates from the unit list.
- Ensure list bullets render in editable surfaces by sharing list-related Tailwind class constants across editors/renderers; replace the Ω “insert” behavior with a character palette popover.
File summaries
| File | Description |
|---|---|
| src/lib/firestore/frqRefs.ts | Adds collection/doc refs for self-graded-frqs and refactors ref helpers. |
| src/components/frq/testRenderer.tsx | Extends submit flow to support “queue” vs “self” destinations and routes to grading for self-grade. |
| src/components/frq/test/testModals.tsx | Updates submission modal to offer “Grade It Myself” vs sending to graders. |
| src/components/frq/responseEditor.tsx | Adds special-character palette with caret save/restore; applies shared list classes so bullets render. |
| src/components/frq/gradingRenderer.tsx | Supports self-grading mode, writes to the correct result collection, and routes to feedback after self-grade. |
| src/components/frq/editorRenderer.tsx | Adds shared admin editor back links + unsaved-change blocker; adjusts header layout to prevent truncation. |
| src/components/frq/editor/richPromptEditor.tsx | Restores rich-text syntax hint by composing it into the provided placeholder. |
| src/components/article-creator/custom_questions/RichTextEditor.tsx | Applies shared list classes so pasted lists render correctly during editing. |
| src/components/article-creator/custom_questions/richText.ts | Introduces shared list class constants (UNORDERED_LIST_CLASSES, ORDERED_LIST_CLASSES, RICH_TEXT_LIST_CLASSES). |
| src/components/article-creator/custom_questions/RenderAdvancedTextbox.tsx | Uses shared list class constants when rendering ul/ol. |
| src/components/article-creator/custom_questions/AdvancedTextbox.tsx | Exports RICH_TEXT_SYNTAX_HINT and composes it into default placeholder text. |
| src/app/frq-grading/page.tsx | Fixes grading queue visibility for members; reads from correct collection and adds per-row delete. |
| src/app/frq-grading/[id]/page.tsx | Allows self-grading access for the submission owner; passes self-grading flags to renderer. |
| src/app/frq-feedback/[id]/page.tsx | Falls back to self-graded results when official grade is absent/unreadable; labels self-assessments. |
| src/app/admin/subject/link.tsx | Adds reusable AdminEditorBackLinks shared by MCQ and FRQ editors. |
| src/app/admin/subject/[slug]/page.tsx | Adds immediate delete for FRQ templates; improves FRQ action error handling/formatting. |
| src/app/admin/subject/[slug]/[unit]/test/[id]/page.tsx | Replaces duplicated back-link markup with shared AdminEditorBackLinks. |
| src/app/admin/subject/[slug]/_components/unitFrqs.tsx | Adds per-FRQ delete button in unit FRQ list. |
| src/app/admin/subject/[slug]/_components/unit.tsx | Wires FRQ delete handler through unit component props. |
| src/app/admin/page.tsx | Shows “Ungraded FRQs” panel to all staff roles that can grade (not admin-only). |
| firestore.rules | Updates role checks and adds rules for self-graded-frqs; allows owner operations needed for self-grade flow. |
| firestore.indexes.json | Removes outdated indexes targeting legacy collection groups. |
Review details
- Files reviewed: 22/22 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…ditor-and-self-grading # Conflicts: # firestore.indexes.json
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.
Description
AdminEditorBackLinkscomponent (not a copy), including the unsaved-changes confirm.list-style/padding onul/ol. The list classes the renderer already applied are now shared constants used by both editable surfaces, so they can't drift apart again.AdvancedTextbox, but a passed placeholder was overriding the LaTeX/code/image syntax hint MCQ authors see. The hint is now composed onto the caller's lead-in.Self-grades kept separate from official grades
Self-assessments write to a new
self-graded-frqscollection, nevergraded-frqs. Anyone may score their own attempt however they like, so nothing there carries a grader's authority:graded-frqsstays unwritable by students, official-result queries never filter self-grades out, and the feedback page labels a self-assessment when it shows one. Grading your own work is a self-assessment whatever your access level, so a member can't file their own attempt as official.Pull request type
Please check the type of change your PR introduces:
A summary of the change, anything else that will help review this PR
Demo
#1 & #3 — the editor is now escapable

The full-screen editor had no navbar and zero links. It now carries the same back-to-Subject / back-to-Admin links the MCQ test editor uses, from a shared
AdminEditorBackLinkscomponent. The header moved off equal thirds, so "2 points total" is no longer truncated.#2 — FRQs can be deleted

Destructive delete button per row, matching the tests list.
#4 — bullets render; Ω is a palette

Preflight was stripping list markers; the classes are now shared with the renderer. The Ω button opens a 99-character palette in six groups instead of inserting a literal "Ω".
#5 — self-grade vs staff queue at submit

"Grade It Myself" runs the grading UI on your own submission and writes to
self-graded-frqs; "Submit to FiveHive Graders" sends it to the staff queue.How Has This Been Tested? How can the reviewer test it?
Reviewer steps:
Checklist