137 lines
5.0 KiB
Markdown
137 lines
5.0 KiB
Markdown
# State Management
|
|
|
|
> State conventions for server-rendered JSP pages.
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
This project does not use React/Vue state libraries or SPA stores. State should
|
|
flow through the Servlet/JSP request cycle unless a future explicit decision
|
|
changes the frontend architecture.
|
|
|
|
---
|
|
|
|
## State Categories
|
|
|
|
- Request attributes: page data, validation errors, form echoes, table rows,
|
|
reports, and short result messages for a single render.
|
|
- Session attributes: authenticated user identity, role, permission summary,
|
|
and short-lived flash-style messages when redirects are used.
|
|
- Database state: books, categories, readers, borrowing records,
|
|
administrators, permissions, and logs stored in MySQL through services/DAOs.
|
|
- Form state: submitted by browser forms to Servlets and re-rendered from
|
|
validated request attributes on failure.
|
|
|
|
---
|
|
|
|
## Rules
|
|
|
|
- Keep business state in MySQL, not hidden fields or long-lived browser state.
|
|
- Keep permission decisions server-side.
|
|
- Use redirects after successful mutations such as create/update/delete,
|
|
borrow, return, renew, and permission changes.
|
|
- Do not add Redux, Pinia, client caches, or SPA routing state unless the
|
|
developer explicitly introduces that stack later.
|
|
|
|
---
|
|
|
|
## Scenario: Dashboard Workbench Request Contract
|
|
|
|
### 1. Scope / Trigger
|
|
|
|
- Trigger: the authenticated workbench spans Servlet request attributes,
|
|
service-derived report/catalog/borrowing data, and role-specific JSP display.
|
|
- Route: `GET /dashboard`.
|
|
- JSP path: `WEB-INF/jsp/dashboard.jsp`.
|
|
|
|
### 2. Signatures
|
|
|
|
- Servlet: `DashboardServlet.doGet(HttpServletRequest, HttpServletResponse)`.
|
|
- Services used for page data:
|
|
- `BookService.listCategories()`.
|
|
- `BookService.searchBooks(new BookSearchCriteria())`.
|
|
- `ReaderService.searchReaders(new ReaderSearchCriteria())` for staff reader
|
|
totals.
|
|
- `ReportService.loadReportCenter(AuthenticatedUser actor)` for
|
|
administrator/librarian users.
|
|
- `BorrowingService.searchRecords(actor, new BorrowRecordSearchCriteria())`
|
|
for administrator/librarian users.
|
|
- Request attributes:
|
|
- `currentUser: AuthenticatedUser`.
|
|
- `categories: List<BookCategory>`.
|
|
- `dashboardBooks: List<Book>`.
|
|
- `dashboardMetrics: List<DashboardMetric>`.
|
|
- `reportCenter: ReportCenter` for staff users when report loading succeeds.
|
|
- `dashboardBorrowRecords: List<BorrowRecord>` for staff users.
|
|
- `errorMessage: String` when a service returns a safe failure.
|
|
|
|
### 3. Contracts
|
|
|
|
- Workbench values must come from request attributes populated by the Servlet;
|
|
JSP must not embed operational sample rows, fixed dates, or fake totals.
|
|
- Staff metrics use `ReportCenter` values derived from `books` and
|
|
`borrow_records`, plus reader totals from `ReaderService`; reader fallback
|
|
metrics may derive from `dashboardBooks`.
|
|
- Popular ranking, overdue rows, and borrowing rows render only real service
|
|
results and show empty states when lists are empty.
|
|
- Category filters render from `categories`, the same source used by catalog and
|
|
book-management pages.
|
|
- Role-gated sections stay in JSP conditionals based on `sessionScope.userRole`;
|
|
staff-only data is not requested for reader users.
|
|
|
|
### 4. Validation & Error Matrix
|
|
|
|
- Category load failure -> `categories` is an empty list and `errorMessage` is
|
|
set.
|
|
- Book search failure -> `dashboardBooks` is an empty list and `errorMessage`
|
|
is set.
|
|
- Reader total load failure -> staff metrics fall back to another real
|
|
service-derived metric and `errorMessage` is set.
|
|
- Staff report load failure -> report-backed sections show empty states and
|
|
`errorMessage` is set.
|
|
- Staff borrowing search failure -> `dashboardBorrowRecords` is an empty list
|
|
and `errorMessage` is set.
|
|
- Empty service result -> render a stable empty state, not hard-coded fallback
|
|
sample data.
|
|
|
|
### 5. Good/Base/Bad Cases
|
|
|
|
- Good: a librarian opens `/dashboard` and sees report-backed metrics, current
|
|
borrowing rows, overdue rows, popular ranking, and real book rows.
|
|
- Base: no borrow records exist; the workbench keeps the layout and shows empty
|
|
states for ranking, borrowing, and overdue panels.
|
|
- Bad: `dashboard.jsp` contains names, book IDs, 2024 dates, or counts that do
|
|
not come from request attributes.
|
|
|
|
### 6. Tests Required
|
|
|
|
- Run Maven compile/test for Servlet and JavaBean contract checks.
|
|
- Run standalone service checks covering report, borrowing, catalog/book, and
|
|
permission policy behavior when available.
|
|
- Scan `dashboard.jsp` for static sample names, fixed dates, and decorative
|
|
sample-only values after dashboard changes.
|
|
- Verify staff and reader role conditionals still show only the intended
|
|
sections.
|
|
|
|
### 7. Wrong vs Correct
|
|
|
|
#### Wrong
|
|
|
|
```text
|
|
dashboard.jsp -> hard-coded metric "12,586" and fixed rows like "L20240521001"
|
|
```
|
|
|
|
#### Correct
|
|
|
|
```text
|
|
dashboard.jsp <- DashboardServlet <- ReportService/BookService/ReaderService/BorrowingService
|
|
```
|
|
|
|
---
|
|
|
|
## Page Scripts
|
|
|
|
Small JavaScript can improve interaction, such as confirm dialogs or local form
|
|
helpers, but server-side validation and service-layer rules remain mandatory.
|