Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

03 — User Journey (Library Module)

End-to-end journeys mapped to exact endpoints. Write actions are server-confirmed (no optimistic mutations); conflicts (409) are surfaced as banners, never silent.


1. Add a book to the catalog (librarian/catalog admin)

Discover missing title → [Book form] → POST /api/v1/books (library.controller.ts:27-31)
  → 201 BookDoc → navigate to detail
  → 409 "Book with ISBN ... already exists." (library.service.ts:37-39) → inline error, edit ISBN
  → 400 → field errors (title/author/isbn required: create-book.dto.ts:5-15)
  • Copies default to 1; availableCopies mirrors totalCopies (library.service.ts:41-46).
  • Bulk entry (many titles) is (planned) via catalog import (IMPLEMENTATION_PLAN.md:172,228).

2. Find a book (student / librarian)

Search box (title/author/ISBN) → GET /api/v1/books?q=…&page=1&limit=20 (library.controller.ts:33-41)
  → server regex match (book.repository.ts:26-30) → list rows with availability badge
  → GET /api/v1/books/:id (library.controller.ts:43-47) → detail
  • No filter → full catalog sorted by title asc (library.service.ts:68-74).
  • Category/publisher/status filtering is client-side only (OQ-5).

3. Issue a book to a student (librarian)

Book detail (available) → [Issue form] (student picker + due date)
  → POST /api/v1/books/issue {bookId, studentId, dueDate, notes?} (library.controller.ts:61-65)
  → 201 BorrowRecordDoc (ACTIVE, borrowedAt=now, dueDate as sent) → success → refresh detail
  → 409 "No copies available for borrowing." (library.service.ts:109-111) → availability refreshed
  → 409 "Student already has maximum number of borrowed books." (library.service.ts:116-120) → show count
  → 404 → book deleted meanwhile → back to catalog
  • Side effect: BookIssued domain event (library.service.ts:141-148).

4. Return a book, settle the fine (librarian + bursar)

Borrowed-by-me / active list → select record → [Return form]
  → POST /api/v1/books/return {borrowRecordId, fineAmount?, notes?} (library.controller.ts:67-71)
  → server computes fine = ceil(overdueDays) × 5 (library.service.ts:159,211-217) or uses override
  → 201/200 record: status=RETURNED, returnedAt=now, fineAmount, fineStatus=pending|undefined
  → if fine > 0 → [Pay fine] → POST /api/v1/books/fines/:borrowRecordId/pay (library.controller.ts:85-89)
      → fineStatus: PAID (library.service.ts:203-209)
  → 409 "Book was not actively borrowed." (library.service.ts:155-157) → refresh, record already closed
  • Side effect: BookReturned event with fineAmount (library.service.ts:180-191).

5. Student checks their loans (student / parent)

My loans → GET /api/v1/books/borrows/:studentId/active (library.controller.ts:79-83)
  → active list (populated bookId; borrow-record.repository.ts:31) → cards with due dates
  → GET /api/v1/books/borrows/:studentId (library.controller.ts:73-77) → full history (returned incl.)
  • Overdue detection is client-derived (server has no worker): now > dueDate && status == active → overdue badge + computed fine preview (OQ-2).
  • studentId comes from the student profile state, not a me endpoint (OQ-9).

6. Librarian's overdue sweep (daily)

Overdue view → client asks active borrows for all students? NO — server lacks a list-all-active endpoint.
  Fallback today: per-student active lists from borrowed-by-me screens;
  a server overdue scan + endpoint is (planned) (borrow-record.repository.ts:34-43 exists, unused; IMPLEMENTATION_PLAN.md:228)
  • Until then: librarian sees overdue only when a student returns a book (fine computed) or via the client's derived-overdue badge on a student's borrowed-by-me view.

Journey → screen map

JourneyScreens (05_Screen_Inventory.md)
Add/edit book4 Catalog List → 5 Book Detail → 7 Book Form
Find book4 Catalog List (search) → 5 Book Detail
Issue5 Book Detail → 8 Issue Form
Return + fine6 Borrowed-by-Me → 9 Return Form → fine pay on record
Student loans check6 Borrowed-by-Me (active) → history tab
Overdue sweep10 Overdue View (derived)