You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-[[Asymptote and Multiple Choice]] - diagram sandbox, variable choices, image-backed options, authoring/import flow, and deploy constraints.
34
35
-[[Entry Points]] - now includes the permission-aware `/admin` panel and its grouped staff routes.
@@ -42,7 +43,7 @@ This is the starting index for the [[dbsmo]] codebase knowledge base, generated
42
43
- Main UI routes live under `app/`; API handlers live under `app/api/`.
43
44
- Current import notes include optional same-name image ZIPs for JSON imports, per-problem image uploads in the problem maker, tolerant JSON editor drafts, and explicit all-file batch dry-run/publish/upload actions with compressed/actual-expanded archive limits (sources: `lib/import/json-import.ts`, `lib/import/image-zip.ts`, `lib/import/zip-dry-run.ts`, `app/admin/create/page-client.tsx`, `app/admin/import/json-zip-import-panel.tsx`).
44
45
- Current class/community notes include authored tasks, a mastery heatmap, problem-set writeups with image uploads/voting/deletion, and class announcements pinned on dashboards (sources: `app/users/[username]/page.tsx`, `app/problem-sets/[slug]/writeups/page.tsx`, `app/writeups/page.tsx`, `app/classes/announcement-composer.tsx`, `app/dashboard/page.tsx`, `prisma/schema.prisma`).
45
-
- Saved submissions have an owner/staff-gated [[Attempt Review]]with links from submit results, solved-set locks, set/dashboard history, student detail, and per-set analytics (sources: `app/attempts/[id]/page.tsx`, `app/problem-sets/[slug]/answer-grid.tsx`, `app/dashboard/page.tsx`).
46
+
- Saved submissions have a perfect-solve/staff-gated [[Attempt Review]]plus a redacted per-set [[Submissions]] directory with 20-row pagination, friends/name filters, and score/verdict visibility (sources: `app/attempts/[id]/page.tsx`, `app/problem-sets/[slug]/submissions/page.tsx`, `app/problem-sets/[slug]/answer-grid.tsx`, `app/dashboard/page.tsx`).
46
47
- Cross-set student metrics use the shared evidence-aware [[Performance Analytics]] model; Mastery Index combines proficiency, breadth, and a consistency floor while keeping best-set average/mastery rate visible (sources: `lib/analytics.ts`, `app/leaderboard/page.tsx`).
47
48
- Authoring and imports support sandboxed Asymptote-to-PNG diagrams plus `MULTIPLE_CHOICE` problems with two to 20 LaTeX/image-capable choices; see [[Asymptote and Multiple Choice]] (sources: `lib/asymptote.ts`, `lib/problem-set-authoring.ts`, `lib/import/json-import.ts`, `app/admin/problem-authoring-controls.tsx`).
@@ -62,6 +62,8 @@ The answer grid is client-side and posts to `/api/submit`. It autosaves draft an
62
62
63
63
Submission is persisted in `app/api/submit/route.ts`: it reads bounded JSON, validates through `lib/submission.ts`, checks visibility, grades through `gradeAnswer(...)`, and creates the `Attempt`/`Response` records in a serializable transaction with bounded retries. Perfect-score locking and attempt numbering are decided inside that transaction so concurrent submissions cannot bypass them (sources: `app/api/submit/route.ts`, `lib/submission.ts`, `lib/grading.ts`).
64
64
65
+
The set header links to `/problem-sets/[slug]/submissions`. That server-rendered directory queries only the current 20-row page, orders by submission time, supports friend IDs from `Friendship` and a bounded display-name search, and keeps raw `Response` data out of the list. Verdict and score are visible to authenticated viewers; the submitter can review their own attempt, while other answer reviews require a perfect attempt for the same visible set or `admin:analytics` (sources: `app/problem-sets/[slug]/page.tsx`, `app/problem-sets/[slug]/submissions/page.tsx`, `app/attempts/[id]/page.tsx`, `lib/submissions.ts`, `prisma/schema.prisma`).
66
+
65
67
## Writeup Flow
66
68
67
69
Problem-set writeups are a separate readable/community surface at `/problem-sets/[slug]/writeups`, linked from the set header next to bookmarks. The server page requires auth, verifies set visibility for students, loads writeups with authors/images/votes, and sorts by newest or top score (source: `app/problem-sets/[slug]/writeups/page.tsx`). The sidebar `/writeups` directory lists latest/top writeups across visible sets and supports problem-set-focused search (source: `app/writeups/page.tsx`).
- The current user can review an attempt when `Attempt.userId` matches their database user ID.
19
-
- Staff with `admin:analytics` can review another user's attempt. This currently covers Admin, Teacher, and Analyst according to `lib/permissions.ts`.
18
+
- The submitter can review their own attempt; reviewing another user's attempt requires a perfect attempt for the same problem set.
19
+
- Staff with `admin:analytics` can review any attempt. This currently covers Admin, Teacher, and Analyst according to `lib/permissions.ts`.
20
20
- Unknown and unauthorized attempt IDs both call `notFound()` so the route does not disclose whether another student's submission exists.
21
21
-`proxy.ts` includes `/attempts/:path*` as the broad signed-in boundary, but the page query remains authoritative (sources: `app/attempts/[id]/page.tsx`, `proxy.ts`, `lib/permissions.ts`).
- Immediate submit result and solved-set lock: `app/problem-sets/[slug]/answer-grid.tsx`.
38
38
- Five most recent attempts on a set: `app/problem-sets/[slug]/page.tsx`.
39
+
- Twenty-row recent submissions directory with all/friends scope and name search: `app/problem-sets/[slug]/submissions/page.tsx` and `lib/submissions.ts`.
Pure behavior is covered by `tests/attempt-review.test.ts`; solved-lock review-link output is covered by `tests/answer-grid.test.ts`. The 2026-07-19 Chrome QA used an isolated local Postgres database and verified immediate review navigation, correct/incorrect/skipped rows, row expansion, accepted-answer math, light/dark rendering, set-history discovery, absence of horizontal overflow, and cross-student 404 behavior.
46
+
Pure behavior is covered by `tests/attempt-review.test.ts` and `tests/submissions.test.ts`; solved-lock review-link output is covered by `tests/answer-grid.test.ts`. The submissions list deliberately does not load `Response` data; detailed review remains gated by the perfect-solve/staff rule.
46
47
47
48
Related: [[Components]], [[Data and Storage]], [[Entry Points]], [[Common Tasks]], [[Risks and Pitfalls]].
Copy file name to clipboardExpand all lines: DBSMO/Projects/dbsmo/Common Tasks.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,12 +1,12 @@
1
1
---
2
2
date: 2026-06-26
3
-
updated: 2026-08-04
3
+
updated: 2026-08-05
4
4
type: common-tasks
5
5
tags: [project, architecture, maintenance, dbsmo]
6
6
ai-first: true
7
7
project: "[[dbsmo]]"
8
8
confidence: high
9
-
scanned-commit: f7e0c74
9
+
scanned-commit: working-tree-2026-08-05
10
10
---
11
11
12
12
## For future Claude
@@ -43,7 +43,7 @@ For multiple-choice changes, also update `Problem.options` in `prisma/schema.pri
43
43
44
44
## Change Attempt Review
45
45
46
-
Start with [[Attempt Review]]. The server page and exact owner/staff authorization live in `app/attempts/[id]/page.tsx`; summary/status helpers and unit tests live in `lib/attempt-review.ts`and `tests/attempt-review.test.ts`. Entry links are spread across`app/problem-sets/[slug]/answer-grid.tsx`, `app/problem-sets/[slug]/page.tsx`, `app/dashboard/page.tsx`, `app/admin/students/[id]/page.tsx`, and `app/admin/sets/[id]/analytics/page.tsx`. Keep`/attempts/:path*` in `proxy.ts`, but do not rely on middleware for the per-attempt ownership check.
46
+
Start with [[Attempt Review]]. The server page and exact perfect-solve/staff authorization live in `app/attempts/[id]/page.tsx`; summary/status helpers and unit tests live in `lib/attempt-review.ts`, `lib/submissions.ts`, and `tests/attempt-review.test.ts`/`tests/submissions.test.ts`. The set submission index is`app/problem-sets/[slug]/submissions/page.tsx`, linked beside the theme control in `app/problem-sets/[slug]/page.tsx`; it owns pagination, friend filtering, name search, and redacted list selection. Keep `/attempts/:path*` and`/problem-sets/:path*` in `proxy.ts`, but do not rely on middleware for the per-attempt answer check.
@@ -35,6 +35,7 @@ This note maps important [[dbsmo]] UI/components to their source files and usage
35
35
-`ProblemSetPage` in `app/problem-sets/[slug]/page.tsx`: route page that loads a set by slug, chooses inline-statement vs PDF/file layout, and exposes the current user's five most recent saved attempt reviews.
36
36
-`AnswerGrid` in `app/problem-sets/[slug]/answer-grid.tsx`: client answer form, autosave, review-later state, submit-to-`/api/submit`, result display, direct saved-review links, missed-topic next action, and feedback report dialog. When `ProblemSetPage` detects the set tag `Tests`, it passes the test layout so answer-only/PDF sets render as a 20×3 test answer sheet for 60 underlying `Problem` rows.
37
37
-`AttemptReviewPage` in `app/attempts/[id]/page.tsx`: server-rendered [[Attempt Review]] with a submission identity/verdict summary and expandable question-result rows. It renders statements/assets and accepted answers through `LatexStatement`, and uses `lib/attempt-review.ts` for status, percentage, answer-list, and duration helpers.
38
+
-`ProblemSetSubmissionsPage` in `app/problem-sets/[slug]/submissions/page.tsx`: server-rendered 20-row recent-submission table with all/friends scope, bounded name search, score/verdict rows, responsive mobile cards, and answer-review links gated by a perfect set solve or `admin:analytics`. `lib/submissions.ts` holds the page and visibility helpers.
38
39
-`BookmarkButton` in `app/problem-sets/[slug]/bookmark-button.tsx`: client bookmark toggle backed by `/api/problem-sets/[id]/bookmark`.
39
40
- Writeup header link in `app/problem-sets/[slug]/page.tsx`: icon link next to `BookmarkButton` that opens `/problem-sets/[slug]/writeups`.
40
41
-`WriteupsPage` and `WriteupsClient` in `app/problem-sets/[slug]/writeups/`: server/client pair for set writeups. The server page handles auth, set visibility, sorting, and initial data; the client component handles the composer, image selection, optimistic voting, confirm-delete controls, and feed cards rendered with `LatexStatement`.
@@ -53,7 +53,9 @@ Deployment docs currently use `npx prisma db push` and `npx prisma generate`, no
53
53
5. Grades each answer with `gradeAnswer(...)`.
54
54
6. Creates one `Attempt` and many `Response` records in a transaction.
55
55
56
-
Saved attempts are read by `/attempts/[id]` for [[Attempt Review]]. The page joins `Attempt.user`, `Attempt.problemSet` assets/file, and each `Response.problem`, then sorts responses by `Problem.number`. It exposes raw/normalized answers, correctness, points, accepted answers, grader notes, and explanations only to the attempt owner or a user with `admin:analytics`; unauthorized IDs resolve through `notFound()` (sources: `app/attempts/[id]/page.tsx`, `lib/attempt-review.ts`, `lib/permissions.ts`). 7. Returns attempt number, score, percentage, and per-problem result summary.
56
+
Saved attempts are read by `/attempts/[id]` for [[Attempt Review]]. The page joins `Attempt.user`, `Attempt.problemSet` assets/file, and each `Response.problem`, then sorts responses by `Problem.number`. It exposes raw/normalized answers, correctness, points, accepted answers, grader notes, and explanations only to a viewer with a perfect attempt for that set or a user with `admin:analytics`; unauthorized IDs resolve through `notFound()` (sources: `app/attempts/[id]/page.tsx`, `lib/attempt-review.ts`, `lib/permissions.ts`, `lib/submissions.ts`). It returns attempt number, score, percentage, and per-problem result summary.
57
+
58
+
`/problem-sets/[slug]/submissions` is a redacted attempt index. It queries at most 20 rows per page, filters by all/friends scope and display name, and selects only attempt summary fields plus display-safe user identity. It never selects `Response` rows. `lib/submissions.ts` centralizes the page-size, verdict, percentage, and answer-visibility rules. The set is still visible to students only through `isVisibleToStudent(...)` (sources: `app/problem-sets/[slug]/submissions/page.tsx`, `lib/submissions.ts`, `lib/visibility.ts`).
@@ -49,7 +49,8 @@ Deployment flow is documented in `SETUP.md`: install dependencies, run `npx pris
49
49
50
50
-`/problem-sets` - browse/filter/sort problem sets with recommendations, assignments/bookmarks/practice views, media/status/category filters, search, and pagination (source: `app/problem-sets/page.tsx`).
51
51
-`/problem-sets/[slug]` - set detail and answer entry, with inline statements or PDF fallback and file/video/solution display (source: `app/problem-sets/[slug]/page.tsx`).
52
-
-`/attempts/[id]` - saved [[Attempt Review]] for the attempt owner or staff with `admin:analytics`; unauthorized and unknown IDs both return 404 (source: `app/attempts/[id]/page.tsx`).
52
+
-`/attempts/[id]` - saved [[Attempt Review]] for the attempt owner, for a viewer who has solved the set perfectly, or for staff with `admin:analytics`; unauthorized and unknown IDs both return 404 (source: `app/attempts/[id]/page.tsx`, `lib/submissions.ts`).
53
+
-`/problem-sets/[slug]/submissions` - authenticated recent-submission directory for a visible set. It shows 20 newest attempts per page, supports all/friends scope and bounded name search, exposes verdict/score to signed-in viewers, and links to answer review only after a perfect solve or for analytics staff (source: `app/problem-sets/[slug]/submissions/page.tsx`, `lib/submissions.ts`).
53
54
-`/problem-sets/[slug]/writeups` - set writeup feed/composer with latest/top sorting, image attachments, and voting (sources: `app/problem-sets/[slug]/writeups/page.tsx`, `app/problem-sets/[slug]/writeups/writeups-client.tsx`).
54
55
-`/writeups` - global writeups directory from the sidebar with latest/top views and problem-set search (source: `app/writeups/page.tsx`).
55
56
-`/practice` - practice-mode UI backed by tags/next/submit APIs (source: `app/practice/page.tsx`).
Copy file name to clipboardExpand all lines: DBSMO/Projects/dbsmo/Risks and Pitfalls.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,12 +1,12 @@
1
1
---
2
2
date: 2026-06-26
3
-
updated: 2026-08-04
3
+
updated: 2026-08-05
4
4
type: risks
5
5
tags: [project, architecture, risks, dbsmo]
6
6
ai-first: true
7
7
project: "[[dbsmo]]"
8
8
confidence: high
9
-
scanned-commit: f7e0c74
9
+
scanned-commit: working-tree-2026-08-05
10
10
---
11
11
12
12
## For future Claude
@@ -51,7 +51,7 @@ Multiple-choice images are normal problem-set assets embedded in `Problem.option
51
51
52
52
## Attempt Reviews Expose Answer Keys
53
53
54
-
`/attempts/[id]` intentionally shows accepted answers and explanations after submission. Its database join therefore handles assessment-sensitive data. Preserve both checks in `app/attempts/[id]/page.tsx`: ordinary users must own the `Attempt`, and non-owners must have `admin:analytics`. Keep unauthorized IDs on the same `notFound()` path as missing IDs, and do not move answer keys into a client API without an equivalent exact authorization boundary (sources: `app/attempts/[id]/page.tsx`, `lib/permissions.ts`, [[Attempt Review]]).
54
+
`/attempts/[id]` intentionally shows accepted answers and explanations after submission. Its database join therefore handles assessment-sensitive data. Preserve the check in `app/attempts/[id]/page.tsx`: the submitter may review their own attempt, while another viewer must have a perfect attempt for the same visible set or `admin:analytics`. The submissions index must remain redacted and must not select `Response` rows. Keep unauthorized IDs on the same `notFound()` path as missing IDs, and do not move answer keys into a client API without an equivalent exact authorization boundary (sources: `app/attempts/[id]/page.tsx`, `app/problem-sets/[slug]/submissions/page.tsx`, `lib/submissions.ts`, `lib/permissions.ts`, [[Attempt Review]]).
55
55
56
56
Writeups intentionally remain accessible even when submissions are locked or the user has not submitted. Do not reuse submission-lock logic to hide `/problem-sets/[slug]/writeups`; only normal auth and set visibility should gate that page (sources: `app/problem-sets/[slug]/writeups/page.tsx`, `app/api/problem-sets/[id]/writeups/route.ts`).
0 commit comments