完成报表中心
This commit is contained in:
@@ -29,9 +29,6 @@ Implemented scaffold tables:
|
||||
status.
|
||||
- `readers`: reader profiles, optional login-account linkage, borrowing
|
||||
eligibility, contact information, and management status.
|
||||
|
||||
Planned module tables:
|
||||
|
||||
- `borrow_records`: book-reader borrowing, return, renew, and overdue data.
|
||||
|
||||
Record new schema changes in `src/main/resources/db/schema.sql` and update this
|
||||
@@ -427,6 +424,95 @@ borrowing/manage.jsp -> JDBC -> UPDATE books SET available_copies = ...
|
||||
borrowing/form.jsp -> BorrowingManagementServlet -> BorrowingService -> BorrowRecordDao -> borrow_records + books in one transaction
|
||||
```
|
||||
|
||||
## Scenario: Report Center Slice
|
||||
|
||||
### 1. Scope / Trigger
|
||||
|
||||
- Trigger: the report center adds staff-only operational reporting across
|
||||
`books`, `readers`, and `borrow_records` without adding report tables.
|
||||
- Schema path: `src/main/resources/db/schema.sql`.
|
||||
- JSP path: `WEB-INF/jsp/reports/dashboard.jsp`.
|
||||
|
||||
### 2. Signatures
|
||||
|
||||
- Entity signatures:
|
||||
- `InventorySummary(totalTitles, totalCopies, availableCopies,
|
||||
unavailableOrEmptyTitles)`.
|
||||
- `BorrowingSummary(activeLoans, returnedLoans, overdueLoans)`.
|
||||
- `OverdueReportRow(readerIdentifier, readerName, bookIdentifier,
|
||||
bookTitle, dueAt, overdueDays)`.
|
||||
- `PopularBookReportRow(bookIdentifier, title, author, borrowCount)`.
|
||||
- `ReportCenter(inventorySummary, borrowingSummary, overdueRows,
|
||||
popularBooks)`.
|
||||
- DAO signatures: `ReportDao.loadInventorySummary()`,
|
||||
`loadBorrowingSummary()`, `findOverdueRows()`, and
|
||||
`findPopularBooks(int limit)`.
|
||||
- Service signature: `ReportService.loadReportCenter(AuthenticatedUser actor)`
|
||||
returning `ServiceResult<ReportCenter>`.
|
||||
- Servlet route: `GET /reports`.
|
||||
- Protected permission: `/reports` requires `VIEW_REPORTS`.
|
||||
|
||||
### 3. Contracts
|
||||
|
||||
- Report data is read-only and derived from existing `books`, `readers`, and
|
||||
`borrow_records` rows; do not introduce aggregate/cache tables for the MVP.
|
||||
- `unavailableOrEmptyTitles` counts book rows where `books.status` is not
|
||||
`available` or `books.available_copies <= 0`.
|
||||
- `activeLoans` counts active borrow rows where `returned_at IS NULL`.
|
||||
- `returnedLoans` counts rows with `status = returned`.
|
||||
- `overdueLoans` and overdue rows use the derived rule
|
||||
`status = active AND returned_at IS NULL AND due_at < CURRENT_TIMESTAMP`.
|
||||
- Popular book ranking groups by book and orders by borrow record count
|
||||
descending, with a service/DAO limit for the top rows.
|
||||
- `ReportServlet` sets the `reportCenter` request attribute on success and
|
||||
`errorMessage` on safe service failure.
|
||||
- JSP pages render JavaBean properties only; they must not call DAOs or embed
|
||||
SQL.
|
||||
- Dashboard, role-home, and header navigation should expose reports only to
|
||||
administrator/librarian users.
|
||||
|
||||
### 4. Validation & Error Matrix
|
||||
|
||||
- Missing or unauthenticated actor -> `You do not have permission to view reports.`
|
||||
- Reader actor -> `You do not have permission to view reports.`
|
||||
- DAO failure while loading any report section -> log server-side details and
|
||||
return `Report service is temporarily unavailable. Please try again later.`
|
||||
- Empty overdue list -> render a stable empty state, not an error.
|
||||
- Empty popular ranking -> render a stable empty state, not an error.
|
||||
|
||||
### 5. Good/Base/Bad Cases
|
||||
|
||||
- Good: a librarian opens `/reports` and sees inventory totals, borrowing
|
||||
counts, active overdue rows, and top borrowed books.
|
||||
- Base: no borrowing records exist; summaries show zero counts and tables show
|
||||
empty states.
|
||||
- Bad: a reader reaches `/reports`, a JSP performs `SELECT` queries directly,
|
||||
or report queries update inventory/borrow state.
|
||||
|
||||
### 6. Tests Required
|
||||
|
||||
- Run `ReportServiceCheck` assertions for reader denial, librarian success,
|
||||
report section composition, and DAO failure fallback.
|
||||
- Run `PermissionPolicyCheck` to confirm administrator/librarian roles allow
|
||||
`VIEW_REPORTS` and readers do not.
|
||||
- Scan report JSPs for scriptlets and SQL/JDBC references.
|
||||
- When Maven/Tomcat dependencies are installed, run `mvn clean package` to
|
||||
compile Servlets and package JSP resources.
|
||||
|
||||
### 7. Wrong vs Correct
|
||||
|
||||
#### Wrong
|
||||
|
||||
```text
|
||||
reports/dashboard.jsp -> JDBC -> SELECT COUNT(*) FROM borrow_records
|
||||
```
|
||||
|
||||
#### Correct
|
||||
|
||||
```text
|
||||
reports/dashboard.jsp <- ReportServlet <- ReportService <- ReportDao <- books/readers/borrow_records
|
||||
```
|
||||
|
||||
## Scenario: Login And Permission Scaffold Schema
|
||||
|
||||
### 1. Scope / Trigger
|
||||
|
||||
Reference in New Issue
Block a user