loginAsSecondUser helper backs new specs that cover the
/texts list (own-only scoping, create form, link to
/texts/{id}) and /texts/{id} detail (own access, 403 on
another user's text, owner can add a child node).
new /texts page lets a user manage their own texts (list +
create form linking to /texts/{id}); /texts/{id} reuses
text.js for the node tree, with a back link to /texts. home
gains a 'My texts' link in the header. the admin texts page
now sources its cross-user list from /api/texts/all.
getNodesOfText, createNode, and bulkCreateNodes now require
the session user, look up the target text, and respond 403
unless the user owns the text or is an admin. paves the way
for moving these endpoints out of the admin-only group.
add failing tests asserting 403 when a non-owner tries to
read or write nodes on another user's text, plus admin
bypass. existing tests now attach a session user to mirror
the new controller signature.
open POST /api/texts and node create endpoints to any
authenticated user; expose new /texts and /texts/{id} pages
plus admin-only GET /api/texts/all. ViewController gains
userTexts and userText methods. seed gives Tanach to the
regular user and adds a second non-admin user.
TextRepository gains findByUser; JsonTextRepository and the
fake implement filtering by stored userId. TextController
splits the list endpoint into getMyTexts (own) and
getAllTexts (admin), and getText now requires the session
user, returning 403 to non-owners while admins bypass.
add failing tests for getMyTexts (own-only), getAllTexts
(admin), getText 403 for non-owner, and admin bypass on
getText. existing test_get_one_text updated to pass the
session user via the new request signature.
Text now requires a User on construction. seed a user in
each test setUp that creates a Text directly or through the
fake repository so the suite remains green.
cover that the created Text carries the supplied User, that
the controller persists the user from the session attribute,
and that any userId in the request body is ignored.
include the user when rebuilding Text instances in find and
getAll, preserving the rule that lookup methods return new
instances rather than stored references.
drop UserRepository dependency; controller now passes the
authenticated User directly via CreateTextRequest, eliminating
a redundant repository lookup.
introduce closeAllAddForms which strips every add-child and
bulk-add input/button from the tree, and call it at the start of
toggleAddForm and toggleBulkAddForm (after the same-li toggle-off
short-circuit, so clicking the same trigger still closes its own
form). enforces a single open add form across the whole tree.
assert that opening any add-child or bulk-add form closes any
other open add form across the tree. currently fails: each toggle
function only checks for an open form on its own li.
extract the save-bulk handler into a submit closure shared by the
save button click and a keydown listener on both the title and
count inputs. focus the title input as soon as the form opens.
assert that pressing enter from either the bulk-title or
bulk-count input submits the bulk add form. currently fails:
only the save-bulk button click triggers the post.
extract the save-child handler into a submit closure shared by
the save button click and a keydown listener on the input. also
focus the input as soon as the form opens so the user can type
and hit enter without touching the mouse.
introduce a module-level expandedNodeIds set that tracks which
nodes the user has manually expanded. renderTree consults the set
when deciding initial visibility (falling back to the depth-based
default for a fresh load), the toggle click handler keeps the set
in sync, and both add-child save handlers add the parent's id
before triggering the re-fetch. on a fresh load the set starts
empty so root-only-open behavior is unchanged and the existing
toggle tests keep passing.
assert that a non-root parent that the user expanded stays expanded
after adding a child. currently fails: fetchAndRenderNodes wipes
and rebuilds the tree with depth-based default visibility, so any
manually expanded non-root collapses on every save.
reuse the centered auth-card shell for the 403 page so the error
state matches the visual language of the rest of the app, with a
primary back-to-home action.
apply the shared auth-shell + auth-card layout to the register
template, mirroring the login page. ids and the #register-error
element are preserved for the existing cypress auth tests.
introduce .auth-shell and .auth-card classes for the centered,
narrow-card layout shared by login and register, then apply them
to the login template. form ids and the #login-error element are
preserved so the existing cypress auth flows still target them.
wrap the admin page in the shared header (with the logout button)
and present the texts entry-point as a card-link in a list-cards
list. the #texts and #logout id hooks used by cypress are
preserved.
apply the page shell to the text detail page and add a scoped
.node-tree style block to app.css. the tree dom rendered by text.js
must keep ul/li with buttons and inputs as direct children of each
li (cypress relies on > selectors), so styling is applied entirely
via descendant selectors without wrapping the rendered nodes.
apply the page shell to the admin texts page and present each
existing text as a card-link plus the new-text form as a card with
a primary submit button. ids (#texts-list, #newTextName, #submit,
#back) and the name attribute on the input are preserved so the
existing cypress flows continue to work.
wrap the today page in the shared header + container/stack shell,
render scheduled nodes as cards via list-cards, and add a muted
empty-state message that toggles when no nodes are scheduled.
existing #scheduled-nodes-list and li selectors used by cypress
tests are preserved (the empty message lives in its own element).
apply the new design system to the home page: wrap content in a
container/stack shell with a site-header for the logout and today
links, render the texts list as a vertical stack of cards via the
list-cards primitive, and dress the create plan modal with the new
modal/btn classes. js renders each text as an li.card with the
create-plan button preserved so existing cypress hooks (li,
.create-plan, .plan-name, .save-plan, .cancel-plan, ids) keep
matching.
extend app.css with the every-layout style primitives (container,
stack, cluster, center) used to compose page shells, plus a small
component layer: site-header, btn (primary/secondary/danger), card
and card-link, list-cards, modal, error and a few utility classes.
no template changes here - templates start adopting these classes
in the per-page styling commits that follow.
add a stylesheet link and the standard responsive viewport meta tag
to every page template. purely additive - no markup or selector
changes - so existing cypress assertions and page js id hooks remain
intact. with this commit every page picks up the base styling from
app.css.
introduce a single shared stylesheet under public/css. this first
section covers a minimal reset, warm/readable design tokens (color,
typography, spacing, radii, shadows), and base element styling for
headings, links, lists, forms, and buttons. layout primitives and
component classes follow in subsequent commits.