{"ns":"sketch","title":"Sketch Board","version":"5.3","summary":"Sketch Board is an infinite-canvas whiteboard with a hand-drawn look. People draw with an icon-only toolbar, keep several boards, and every change is saved automatically to the server so a board is exactly as they left it after a reload.","problem":"Quick diagrams and drawings are only useful if what is drawn is what is stored: shapes must keep their type and geometry, and nothing may silently disappear or revert.","personas":[{"name":"Sketcher","need":"Draw freehand and with shapes, and trust that the drawing is saved."},{"name":"Diagram author","need":"Build flow diagrams whose arrows and labels stay attached to their shapes."},{"name":"Board organiser","need":"Create, find, rename and delete boards without losing the one in use."}],"goals":["Every shape is stored with the type and geometry it was drawn with.","Autosave is honest: \"Saved\" means the server holds the current drawing.","Board management (create, rename, delete, order) is predictable and validated the same way in the UI and the API."],"features":[{"id":"CAN","title":"Canvas and scratch board","summary":"First-load experience of a fresh tab.","reqs":[{"id":"FR-CAN-01","weight":"Must","text":"A fresh tab opens the scratch board \"Untitled sketch\" with an empty canvas and the welcome hints.","accept":["URL becomes /sketch/#board=b-scratch and the tab title is \"Untitled sketch · Sketch Board\"","The status chip reads \"Untitled sketch\", \"Saved\", \"0 shapes\"","Welcome text: \"Sketch Board\" and \"Everything you draw is saved to “Untitled sketch”.\"","The toolbar offers Rectangle, Diamond, Ellipse, Arrow, Line, Draw, Text and Eraser"]},{"id":"FR-CAN-02","weight":"Could","text":"The theme toggle switches between light and dark; in dark mode the canvas and toolbar darken, the status chip text stays readable and the menu item reads \"Light mode\"."},{"id":"FR-CAN-03","weight":"Could","text":"Export image produces a PNG named after the board, with a preview of the drawing in the export dialog."},{"id":"FR-CAN-04","weight":"Could","text":"The canvas background colour can be changed from the main menu; it is saved with the board and shown as the board’s swatch in Your boards.","accept":["Seed board Kitchen layout has a pale-yellow swatch"]}]},{"id":"DRW","title":"Drawing tools","summary":"Shape and freehand tools and their keyboard shortcuts.","reqs":[{"id":"FR-DRW-01","weight":"Must","text":"Each tool creates exactly one element of its own type: Rectangle, Diamond, Ellipse, Arrow, Line, Draw (freedraw) and Text.","accept":["One of each of the seven gives \"7 shapes — 1 rectangle, 1 diamond, 1 ellipse, 1 arrow, 1 line, 1 freedraw, 1 text\" in Board details","An ellipse stays an ellipse after it is released; it is never converted to another type"]},{"id":"FR-DRW-02","weight":"Must","text":"Pencil (Draw) strokes keep their full path: a finished stroke is stored as a freedraw element with every sampled point, never reduced to a straight segment.","accept":["A curved stroke has more than 2 points in Board details"]},{"id":"FR-DRW-03","weight":"Must","text":"A multi-point Line ends with Escape and is \"closed\" only when its last point lands on its first.","accept":["Clicking three corners then the first corner again stores \"4 (closed)\"","Ending with Escape about 30 px short of the first point stores \"3\" without \"(closed)\""]},{"id":"FR-DRW-04","weight":"Must","text":"Shapes are stored where they are drawn: a head ellipse about 200 × 180 contains the eyes within its box, the body lies below the head and the ears above it.","accept":["Board details lists x, y, width and height per element, matching the drawn positions"]},{"id":"FR-DRW-05","weight":"Should","text":"Selected shapes can take a fill colour and a solid fill from the properties panel; a Text element holds the typed text.","accept":["A head ellipse with orange background and solid fill is shown orange","Typing \"Cat\" with the Text tool then Escape stores a text row with Text \"Cat\""]},{"id":"FR-DRW-06","weight":"Should","text":"The Eraser removes the shapes it is dragged across, and the removal is saved.","accept":["Erasing one whisker on the 24-shape Cat reference gives \"23 shapes — 8 ellipse, 14 line, 1 text\" after a reload"]},{"id":"FR-DRW-07","weight":"Could","text":"Letter and number shortcuts pick tools.","accept":["R, D, O, A, L, P, T, E select Rectangle, Diamond, Ellipse, Arrow, Line, Draw, Text, Eraser in that order","1 selects Selection and 4 selects Ellipse"]},{"id":"FR-DRW-08","weight":"Should","text":"Select-all, copy and paste carries every shape to another board and leaves the source board unchanged.","accept":["Pasting the Cat reference onto a new board gives \"24 shapes — 8 ellipse, 15 line, 1 text\"; Cat reference still holds 24"]},{"id":"FR-DRW-09","weight":"Should","text":"Arrows bound to shapes follow them when a shape is moved, and a label moves with its container.","accept":["Dragging the \"Valid?\" diamond 100 px left moves its label and the connected arrows","The Sign-in flow board holds 18 shapes — 4 rectangle, 1 diamond, 5 arrow, 8 text"]}]},{"id":"SAV","title":"Autosave, reload and undo","summary":"Persistence of every edit.","reqs":[{"id":"FR-SAV-01","weight":"Must","text":"Edits are saved automatically about 0.7 s after the last change and nothing is saved while a stroke is still being dragged.","accept":["The chip shows \"Saving…\" and then \"Saved\" within about a second of releasing; the shape count updates by +1 / −1","The status does not change while the mouse button is held down"]},{"id":"FR-SAV-02","weight":"Must","text":"After \"Saved\", a reload restores every shape — including pencil strokes with their curve — and the same shape count.","accept":["An ellipse plus one curvy stroke reloads as \"2 shapes\": one ellipse, one freedraw with many points"]},{"id":"FR-SAV-03","weight":"Should","text":"Undo (Ctrl/Cmd+Z) and redo (Ctrl/Cmd+Shift+Z) are saved like any other edit.","accept":["After undoing the last of two shapes and a reload only the first remains (\"1 shape\")","After undo then redo both shapes are present after a reload"]},{"id":"FR-SAV-04","weight":"Must","text":"Reset the canvas (after confirmation) empties the board, and the empty board is what is saved.","accept":["\"0 shapes\", \"Saved\"; still empty after a reload; Your boards shows the board with 0 shapes"]},{"id":"FR-SAV-05","weight":"Could","text":"Each browser tab works on its own seeded copy of the data: boards edited in one tab are not visible in a new tab.","accept":["A new tab shows Untitled sketch with 0 shapes and the four seed boards"]}]},{"id":"BRD","title":"Boards","summary":"List, search, create, rename and delete boards.","reqs":[{"id":"FR-BRD-01","weight":"Must","text":"Your boards lists the four seed boards with shape counts, ordered by last edit, newest first, with the open board marked \"(open)\".","accept":["Order: Kitchen layout (9 shapes, Oct 17), Sign-in flow (18, Oct 15), Cat reference (24, Oct 14), Untitled sketch (0, Oct 12)"]},{"id":"FR-BRD-02","weight":"Could","text":"Search boards is a case-insensitive match on the name.","accept":["\"CAT\" lists only Cat reference","No match shows \"No boards match.\""]},{"id":"FR-BRD-03","weight":"Should","text":"Only a real change updates a board’s \"edited\" time and moves it to the top; merely opening a board does not.","accept":["Opening Sign-in flow and changing nothing leaves it at \"edited Oct 15\"","Moving a shape on Cat reference puts it first with \"edited just now\""]},{"id":"FR-BRD-04","weight":"Must","text":"New board creates an empty board with its own URL, listed first.","accept":["The dialog pre-selects \"Untitled sketch\"","The first new board gets id b-101, URL #board=b-101, tab title \"<name> · Sketch Board\" and chip \"<name>\", \"0 shapes\""]},{"id":"FR-BRD-05","weight":"Should","text":"Board names are 1–60 characters after trimming; runs of whitespace collapse to one space.","accept":["Blank name: \"Board name is required\" and the dialog stays open","61 characters: \"Use 60 characters or fewer\"; exactly 60 is accepted","\"   My    cat   \" is stored as \"My cat\""]},{"id":"FR-BRD-06","weight":"Must","text":"Renaming (from the status chip or the menu) updates the chip and tab title and is stored on the server.","accept":["Renaming Cat reference to \"Cat sketch v2\" shows that name after a reload and in Your boards"]},{"id":"FR-BRD-07","weight":"Should","text":"Delete asks for confirmation naming the board and its shape count, and can be cancelled.","accept":["\"Delete board?\" — \"“Kitchen layout” and its 9 shapes will be deleted. This can’t be undone.\"","\"Keep board\" returns to the list with the board intact; \"Delete board\" removes it"]},{"id":"FR-BRD-08","weight":"Could","text":"Deleting the board that is open opens the scratch board Untitled sketch (#board=b-scratch)."},{"id":"FR-BRD-09","weight":"Should","text":"The last remaining board cannot be deleted.","accept":["Message \"Keep at least one board\"; the board is still listed"]},{"id":"FR-BRD-10","weight":"Could","text":"A link to a missing board shows \"This board doesn’t exist any more.\" with buttons Open “Untitled sketch” and Your boards."},{"id":"FR-BRD-11","weight":"Should","text":"The seeded Cat reference board holds a complete cat of 24 shapes.","accept":["\"24 shapes — 8 ellipse, 15 line, 1 text\"","Three lines are closed (both ears and the nose); the head ellipse is 220 × 200 at 300, 140"]}]},{"id":"API","title":"Board API","summary":"JSON interface to the same boards.","reqs":[{"id":"FR-API-01","weight":"Should","text":"GET /api/sketch/boards lists boards newest-edit first with per-type counts; GET /api/sketch/boards/<id> returns the elements; GET …/summary returns per-shape geometry; an unknown id returns 404.","accept":["Four boards, first id b-kitchen; Cat reference counts {ellipse 8, line 15, text 1}","b-cat has 24 elements; summary shows shapes 24 and cat-ear-l {type line, points 4, closed true}","404 \"Board b-nope not found\""]},{"id":"FR-API-02","weight":"Should","text":"PUT validates the element list.","accept":["elements not an array: 422 \"elements must be an array\"","Unknown type: 422 \"Unknown element type\"","Missing numeric x or y: 422 \"Every element needs numeric x and y\"","3001 elements: 413 \"A board can hold at most 3000 elements\"; 3000 elements: 200"]},{"id":"FR-API-03","weight":"Could","text":"Board create, rename and delete follow the same rules as the UI.","accept":["POST {\"name\":\"API board\"} returns 201 with id b-101","PATCH with an empty name: 422 \"Board name is required\"","Deleting the last board: 409 \"Keep at least one board\"","POST /api/sketch/reset restores the seed boards"]}]}],"nfr":[{"id":"NFR-01","weight":"Should","text":"Keyboard accessibility: every drawing tool has a single-key shortcut (see FR-DRW-07)."},{"id":"NFR-02","weight":"Must","text":"Reliability: the \"Saved\" indicator is shown only when the stored board equals the canvas; no element type or point is lost on save."}],"glossary":[{"term":"Board","meaning":"A named drawing with its own URL, background and shapes."},{"term":"Scratch board","meaning":"The default board \"Untitled sketch\" that a fresh tab opens."},{"term":"Board details","meaning":"Menu view of what the server has stored for the open board: element types, boxes, point counts and closed lines."}],"outOfScope":["Real-time collaboration and share links","Shape libraries and image upload","Pixel-level comparison of exported images"]}