Check-my-work attachments, smart review follows deletions, GPL-3.0-only
- "Check my work" now takes photos and documents of the attempt: documents
are read in the browser into text, photos go to /api/homework as
solutionImages and are transcribed by the vision model before the check
("Reading your solution..."). The finished attempt comes back in
meta.solutionText and is stored as the record's attempt, so "Redo"
re-checks the same work without keeping the files.
- Deleting a deck now drops its due schedules and mistakes from the library's
smart review immediately (the counts resolve against the live deck list);
Undo brings them back, because the learning data itself is never erased.
- The phone override for the glacier blobs was still at 0.1/0.2: it is now a
quarter of the original value there too (0.025/0.05), matching the desktop.
- License: GPL-3.0-only (LICENSE, package.json, README section).
Tests: phase-3 photos-only API + desktop attachment checks (28/28), review
suite deck-delete checks (18/18), i18n/mobile/phase-2 green. README:
decisions 57-58. SW -> freezmo-v45.
This commit is contained in:
parent
9d204b85be
commit
d559865a09
13 changed files with 1033 additions and 24 deletions
|
|
@ -106,7 +106,55 @@ async function makeReviewPage(locale = "en") {
|
|||
await context.close();
|
||||
}
|
||||
|
||||
/* 4. health probes are deduplicated ---------------------------------- */
|
||||
/* 4. deleting a deck updates the smart review ------------------------ */
|
||||
{
|
||||
const { context, page } = await makePage(browser);
|
||||
const second = { ...DECK, id: "seed_two", title: "Second deck" };
|
||||
await seed(page, { decks: [DECK, second] });
|
||||
await page.goto(BASE, { waitUntil: "networkidle" });
|
||||
await page.waitForTimeout(800);
|
||||
await seedLearning(page, {
|
||||
answers: [wrongAnswer("seed_deck", "a1"), wrongAnswer("seed_two", "a2")],
|
||||
srs: [dueSrs("seed_deck", "a1"), dueSrs("seed_two", "a2")],
|
||||
});
|
||||
await page.reload({ waitUntil: "networkidle" });
|
||||
await page.waitForTimeout(900);
|
||||
const counts = () =>
|
||||
page.evaluate(() => document.body.innerText.match(/(Review due · \d+ due|Mistakes · \d+ mistakes?)/g) ?? []);
|
||||
const before = await counts();
|
||||
check(
|
||||
"deck delete: two decks are due with two mistakes",
|
||||
JSON.stringify(before) === JSON.stringify(["Review due · 2 due", "Mistakes · 2 mistakes"]),
|
||||
JSON.stringify(before),
|
||||
);
|
||||
await page
|
||||
.locator("li")
|
||||
.filter({ hasText: "Sky deck" })
|
||||
.first()
|
||||
.getByRole("button", { name: "Deck actions" })
|
||||
.click();
|
||||
await page.waitForTimeout(500);
|
||||
await page.getByRole("button", { name: "Delete deck" }).click();
|
||||
await page.waitForTimeout(800);
|
||||
const after = await counts();
|
||||
check(
|
||||
"deck delete: its schedules and mistakes leave the review",
|
||||
JSON.stringify(after) === JSON.stringify(["Review due · 1 due", "Mistakes · 1 mistake"]),
|
||||
JSON.stringify(after),
|
||||
);
|
||||
const undo = page.getByRole("button", { name: /Undo/ });
|
||||
if ((await undo.count()) > 0) await undo.click();
|
||||
await page.waitForTimeout(800);
|
||||
const restored = await counts();
|
||||
check(
|
||||
"deck delete: Undo brings the counts back",
|
||||
JSON.stringify(restored) === JSON.stringify(["Review due · 2 due", "Mistakes · 2 mistakes"]),
|
||||
JSON.stringify(restored),
|
||||
);
|
||||
await context.close();
|
||||
}
|
||||
|
||||
/* 5. health probes are deduplicated ---------------------------------- */
|
||||
{
|
||||
const { context, page } = await makePage(browser);
|
||||
await seed(page, { decks: [] });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue