做读者档案、联系方式、借阅资格功能
This commit is contained in:
@@ -27,10 +27,11 @@ Implemented scaffold tables:
|
||||
- `book_categories`: category names and descriptions for catalog grouping.
|
||||
- `books`: book information, category reference, inventory counts, and catalog
|
||||
status.
|
||||
- `readers`: reader profiles, optional login-account linkage, borrowing
|
||||
eligibility, contact information, and management status.
|
||||
|
||||
Planned module tables:
|
||||
|
||||
- `readers`: reader profiles, borrowing eligibility, contact information.
|
||||
- `borrow_records`: book-reader borrowing, return, renew, and overdue data.
|
||||
|
||||
Record new schema changes in `src/main/resources/db/schema.sql` and update this
|
||||
@@ -78,6 +79,11 @@ spec with exact table names, key columns, and DAO/service contracts.
|
||||
- `role_permissions.permission_code` must reference `permissions.code`.
|
||||
- `books.status` must match `BookStatus` enum codes: `available`,
|
||||
`unavailable`, and `archived`.
|
||||
- `readers.user_id` may reference `users.id` when a reader profile is linked to
|
||||
a login account.
|
||||
- `readers.status` must match `ReaderStatus` enum codes: `active`,
|
||||
`suspended`, and `inactive`.
|
||||
- `readers.max_borrow_count` must stay between 1 and 50.
|
||||
|
||||
## Scenario: Book Catalog And Management Slice
|
||||
|
||||
@@ -187,6 +193,115 @@ books/form.jsp -> JDBC -> INSERT INTO books using request parameters
|
||||
books/form.jsp -> BookManagementServlet -> BookService -> BookDao -> books
|
||||
```
|
||||
|
||||
## Scenario: Reader Information Management Slice
|
||||
|
||||
### 1. Scope / Trigger
|
||||
|
||||
- Trigger: the reader profile foundation was implemented after login,
|
||||
permissions, catalog search, and book management.
|
||||
- Schema path: `src/main/resources/db/schema.sql`.
|
||||
- JSP paths: `WEB-INF/jsp/readers/manage.jsp` and `readers/form.jsp`.
|
||||
|
||||
### 2. Signatures
|
||||
|
||||
- DAO signatures: `ReaderDao.search(ReaderSearchCriteria criteria)`,
|
||||
`findById(long id)`, `findByIdentifier(String identifier)`,
|
||||
`findByUserId(long userId)`, `create(Reader reader)`,
|
||||
`update(Reader reader)`, and `deactivate(long id)`.
|
||||
- Entity/search signatures: `Reader` fields are `id`, `identifier`,
|
||||
nullable `userId`, nullable `username`, `fullName`, `phone`, `email`,
|
||||
`status`, `maxBorrowCount`, `createdAt`, and `updatedAt`;
|
||||
`ReaderSearchCriteria` fields are `identifier`, `name`, `contact`, and
|
||||
`statusCode`.
|
||||
- Status signature: `ReaderStatus` enum codes are `active`, `suspended`, and
|
||||
`inactive`.
|
||||
- Service signatures: `ReaderService.searchReaders(ReaderSearchCriteria)`,
|
||||
`findReader(long id)`, `createReader(AuthenticatedUser actor, Reader reader)`,
|
||||
`updateReader(AuthenticatedUser actor, Reader reader)`, and
|
||||
`deactivateReader(AuthenticatedUser actor, long id)`, all returning
|
||||
`ServiceResult<T>`.
|
||||
- Management routes: `GET /readers`, `GET /readers/new`,
|
||||
`GET /readers/edit?id=...`, `POST /readers`, `POST /readers/update`, and
|
||||
`POST /readers/delete`.
|
||||
- Protected permission: `/readers*` requires `MANAGE_READERS`.
|
||||
- DB signature: `readers(id, reader_identifier, user_id, full_name, phone,
|
||||
email, status, max_borrow_count, created_at, updated_at)`, with unique keys
|
||||
on `reader_identifier` and nullable `user_id`, indexes on name/contact/status,
|
||||
a foreign key to `users(id)`, and checks for supported status values and
|
||||
borrow-limit range.
|
||||
|
||||
### 3. Contracts
|
||||
|
||||
- `readers.reader_identifier` is the unique user-facing reader ID.
|
||||
- `readers.user_id` is optional; when present, only one reader profile may link
|
||||
to the same login account.
|
||||
- `readers.status` stores the Java `ReaderStatus` code exactly. Soft-delete
|
||||
behavior deactivates the profile by setting status to `inactive`.
|
||||
- Reader searches support partial identifier, full-name, and phone/email
|
||||
contact matching plus exact status filtering.
|
||||
- Servlet controllers parse request fields and set JSP attributes such as
|
||||
`criteria`, `readers`, `reader`, `statuses`, `formValues`, `errors`,
|
||||
`errorMessage`, and `successMessage`.
|
||||
- JSP pages render JavaBean properties only; they must not call DAOs or embed
|
||||
SQL.
|
||||
- Navigation should expose reader management to administrator/librarian users,
|
||||
matching the current `MANAGE_READERS` policy.
|
||||
|
||||
### 4. Validation & Error Matrix
|
||||
|
||||
- Missing identifier or full name -> return to `readers/form.jsp` with field
|
||||
errors.
|
||||
- Missing both phone and email -> return a field error on `phone`.
|
||||
- Invalid phone or email format -> return field errors on `phone` or `email`.
|
||||
- Unsupported status -> return a field error on `status`.
|
||||
- Max borrow count outside 1 to 50 -> return a field error on
|
||||
`maxBorrowCount`.
|
||||
- Non-positive linked `user_id` -> return a field error on `userId`.
|
||||
- Duplicate `reader_identifier` -> return a field error on `identifier`.
|
||||
- Duplicate linked `user_id` -> return a field error on `userId`.
|
||||
- Reader or unauthenticated actor attempts write -> HTTP 403 through
|
||||
authorization filter or service denial.
|
||||
- DAO failure during list/search/write -> log server-side details and return
|
||||
`Reader service is temporarily unavailable. Please try again later.`
|
||||
- Successful create/update/deactivate -> redirect to `/readers` with a short
|
||||
flash message.
|
||||
|
||||
### 5. Good/Base/Bad Cases
|
||||
|
||||
- Good: a librarian creates `RD-1003`, searches by email, edits the borrow
|
||||
limit, and can later deactivate the profile without deleting future borrowing
|
||||
history.
|
||||
- Base: `/readers` with no filters lists reader records ordered by full name
|
||||
and reader identifier.
|
||||
- Bad: normal readers access `/readers`, a JSP opens JDBC, or deleting a reader
|
||||
profile removes rows that future borrow records need to reference.
|
||||
|
||||
### 6. Tests Required
|
||||
|
||||
- Run `ReaderServiceCheck` or equivalent assertions for invalid contact,
|
||||
invalid borrow limit, duplicate identifiers, duplicate linked users, reader
|
||||
write denial, successful librarian CRUD-like operations, search, deactivate,
|
||||
and DAO failure fallback.
|
||||
- Run `PermissionPolicyCheck` to confirm librarians have `MANAGE_READERS` and
|
||||
readers do not.
|
||||
- Scan reader 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
|
||||
readers/form.jsp -> JDBC -> DELETE FROM readers using request parameters
|
||||
```
|
||||
|
||||
#### Correct
|
||||
|
||||
```text
|
||||
readers/form.jsp -> ReaderManagementServlet -> ReaderService -> ReaderDao -> readers.status = inactive
|
||||
```
|
||||
|
||||
## Scenario: Login And Permission Scaffold Schema
|
||||
|
||||
### 1. Scope / Trigger
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{"file": ".trellis/spec/backend/index.md", "reason": "Backend checklist and architecture expectations for verifying the reader-management slice."}
|
||||
{"file": ".trellis/spec/backend/database-guidelines.md", "reason": "Schema, DAO, service, permission, and test expectations to check against."}
|
||||
{"file": ".trellis/spec/backend/error-handling.md", "reason": "Verify controller/service/DAO failures are handled consistently."}
|
||||
{"file": ".trellis/spec/backend/logging-guidelines.md", "reason": "Verify server-side failure logging and protected workflow logging expectations."}
|
||||
{"file": ".trellis/spec/backend/quality-guidelines.md", "reason": "Backend quality gate and review checklist."}
|
||||
{"file": ".trellis/spec/frontend/index.md", "reason": "Frontend checklist for JSP/CSS verification."}
|
||||
{"file": ".trellis/spec/frontend/component-guidelines.md", "reason": "Verify reader JSP forms/tables follow local component conventions."}
|
||||
{"file": ".trellis/spec/frontend/state-management.md", "reason": "Verify request/session/form state handling remains server-rendered."}
|
||||
{"file": ".trellis/spec/frontend/type-safety.md", "reason": "Verify JSP/Servlet validation and display contracts."}
|
||||
{"file": ".trellis/spec/frontend/quality-guidelines.md", "reason": "Frontend JSP/static quality checks."}
|
||||
{"file": ".trellis/tasks/archive/2026-04/00-bootstrap-guidelines/research/project-requirements.md", "reason": "Verify implemented reader management satisfies the original project requirement."}
|
||||
@@ -0,0 +1,13 @@
|
||||
{"file": ".trellis/spec/backend/index.md", "reason": "Backend pre-development checklist and layered architecture overview for JSP/Servlet/MySQL work."}
|
||||
{"file": ".trellis/spec/backend/directory-structure.md", "reason": "Backend package layout and responsibility boundaries for controller, service, DAO, entity, filter, and util classes."}
|
||||
{"file": ".trellis/spec/backend/database-guidelines.md", "reason": "Schema, DAO, query, and existing book-module scenario conventions relevant to adding readers."}
|
||||
{"file": ".trellis/spec/backend/error-handling.md", "reason": "Service/DAO/controller error-handling conventions for user-facing failures and logging."}
|
||||
{"file": ".trellis/spec/backend/logging-guidelines.md", "reason": "Logging boundaries for protected workflows and DAO/service failures."}
|
||||
{"file": ".trellis/spec/backend/quality-guidelines.md", "reason": "Backend checks and review expectations for layered feature work."}
|
||||
{"file": ".trellis/spec/frontend/index.md", "reason": "Frontend pre-development checklist for JSP/CSS work."}
|
||||
{"file": ".trellis/spec/frontend/directory-structure.md", "reason": "JSP and static asset placement conventions for reader-management pages."}
|
||||
{"file": ".trellis/spec/frontend/component-guidelines.md", "reason": "JSP fragment, form, table, and reusable UI conventions."}
|
||||
{"file": ".trellis/spec/frontend/state-management.md", "reason": "Server-rendered request/session/form state conventions."}
|
||||
{"file": ".trellis/spec/frontend/type-safety.md", "reason": "JSP/Servlet validation and JavaBean display contracts."}
|
||||
{"file": ".trellis/spec/frontend/quality-guidelines.md", "reason": "Frontend quality checks for JSP pages and static assets."}
|
||||
{"file": ".trellis/tasks/archive/2026-04/00-bootstrap-guidelines/research/project-requirements.md", "reason": "Original project requirements listing reader information management as a core module."}
|
||||
@@ -0,0 +1,116 @@
|
||||
# brainstorm: 继续完成程序
|
||||
|
||||
## Goal
|
||||
|
||||
Continue the MZH Library Management system from the current scaffold by implementing the next focused business slice after login/permission and book catalog/management: reader information management.
|
||||
|
||||
## What I already know
|
||||
|
||||
* User asked to "继续完成程序" without specifying the next target module.
|
||||
* The project is a Java 11 Maven WAR application using JSP, Servlet, Tomcat, MySQL, and JDBC DAOs.
|
||||
* Current code includes login/logout, authentication and authorization filters, role-aware dashboard/home pages, book catalog search, and administrator/librarian book management.
|
||||
* The previous completed task explicitly left reader profile management, borrowing/returning/renewing/overdue handling, and full reports/statistics out of scope.
|
||||
* Project requirements list these remaining core modules:
|
||||
* Reader information management for profiles, borrowing eligibility, and contact information.
|
||||
* Borrowing and return management for borrow, return, renew, overdue handling, and automatic collection status updates.
|
||||
* Book search/statistics for borrowing rankings, inventory reports, and overdue reports.
|
||||
* System maintenance/logs for key operation logs, backup support, and exception tracing.
|
||||
* Existing permissions already include `manage_readers`, `manage_borrowing`, `view_reports`, `view_system_logs`, and `borrow_books`.
|
||||
* Existing database schema already includes users, roles, permissions, system logs, book categories, and books.
|
||||
* User selected option 1: reader information management.
|
||||
|
||||
## Assumptions (temporary)
|
||||
|
||||
* The next slice should stay consistent with the existing layered structure: JSP/CSS presentation -> Servlet controller -> Service -> DAO -> MySQL.
|
||||
* The work should remain small enough to implement and verify in one Trellis task.
|
||||
* The next module should build on the completed book and permission foundation instead of redesigning the application.
|
||||
|
||||
## Open Questions
|
||||
|
||||
* None currently blocking. Default scope is administrator/librarian reader profile management.
|
||||
|
||||
## Requirements (evolving)
|
||||
|
||||
* Preserve existing login, role permission, dashboard, catalog, and book-management behavior.
|
||||
* Implement reader information management for reader profiles, contact information, borrowing eligibility, and borrowing limits.
|
||||
* Add a `readers` table to `src/main/resources/db/schema.sql`, linked to reader users when applicable.
|
||||
* Support listing/searching readers by reader identifier, name, phone/email, and status.
|
||||
* Provide administrator/librarian reader-management actions for creating, editing, and deleting or deactivating reader profiles.
|
||||
* Track eligibility/status fields needed for later borrowing work, such as active/suspended status and max borrow count.
|
||||
* Link reader management from the existing dashboard or role workspace for users with `MANAGE_READERS`.
|
||||
* Protect reader-management routes with `MANAGE_READERS`; normal readers must not access management screens.
|
||||
* Add or update database schema, DAO, service, servlet, JSP, and checks for the selected slice.
|
||||
* Keep protected workflows guarded by the existing permission model.
|
||||
* Add focused checks for service rules that can run without Tomcat.
|
||||
|
||||
## Acceptance Criteria (evolving)
|
||||
|
||||
* [x] Administrators and librarians can reach reader management pages and create, edit, and delete or deactivate reader profiles.
|
||||
* [x] Reader profiles persist and load through DAO/service layers, not directly from JSPs.
|
||||
* [x] Reader search supports reader identifier, name, contact fields, and status.
|
||||
* [x] Readers cannot reach reader-management write or list actions.
|
||||
* [x] Invalid identifier, name, contact, status, and borrow-limit values return clear user-facing errors.
|
||||
* [x] Existing completed workflows continue to compile and pass checks.
|
||||
* [x] Local compile/test checks pass or blockers are documented.
|
||||
|
||||
## Definition of Done (team quality bar)
|
||||
|
||||
* Tests added/updated where appropriate.
|
||||
* Lint / typecheck / compile checks green where available.
|
||||
* Docs/notes updated if behavior changes.
|
||||
* Rollout/rollback considered if risky.
|
||||
|
||||
## Out of Scope (explicit)
|
||||
|
||||
* Replacing JSP/Servlet with another framework.
|
||||
* Production deployment automation.
|
||||
* Large visual redesign unrelated to the selected workflow.
|
||||
* Implementing every remaining module in one task.
|
||||
* Borrowing, returning, renewing, overdue handling, and borrowing statistics.
|
||||
* Full reader self-service profile editing.
|
||||
|
||||
## Technical Approach
|
||||
|
||||
Use the same layered pattern established by the book module:
|
||||
|
||||
* `readers` schema and demo reader data in `src/main/resources/db/schema.sql`.
|
||||
* Reader entity/search criteria, DAO, JDBC DAO, service interface, and service implementation.
|
||||
* A `ReaderManagementServlet` mapped to `/readers`, `/readers/new`, `/readers/edit`, `/readers/update`, and `/readers/delete` or equivalent.
|
||||
* JSPs under `WEB-INF/jsp/readers/` for list/search and form workflows.
|
||||
* Service-level checks for validation, permission denial, duplicate identifiers, DAO failure fallback, and successful CRUD-like operations.
|
||||
|
||||
## Decision (ADR-lite)
|
||||
|
||||
**Context**: The project already has authentication, permissions, catalog search, and book management. Borrowing workflows need reader profile and eligibility data before they can be implemented cleanly.
|
||||
|
||||
**Decision**: Implement reader information management as the next focused slice.
|
||||
|
||||
**Consequences**: This adds the reader data foundation needed for future borrow/return/renew modules while keeping borrowing workflows and reports out of scope for this task.
|
||||
|
||||
## Technical Notes
|
||||
|
||||
* Current task directory: `.trellis/tasks/04-27-continue-program`.
|
||||
* Relevant previous task: `.trellis/tasks/archive/2026-04/04-27-continue-improve-program/prd.md`.
|
||||
* Project requirements source: `.trellis/tasks/archive/2026-04/00-bootstrap-guidelines/research/project-requirements.md`.
|
||||
* Spec indexes available:
|
||||
* `.trellis/spec/backend/index.md`
|
||||
* `.trellis/spec/frontend/index.md`
|
||||
* File inventory inspected:
|
||||
* `README.md`
|
||||
* `pom.xml`
|
||||
* `src/main/resources/db/schema.sql`
|
||||
* `src/main/webapp/WEB-INF/web.xml`
|
||||
* `src/main/webapp/WEB-INF/jsp/dashboard.jsp`
|
||||
* `src/main/webapp/WEB-INF/jsp/role-home.jsp`
|
||||
* `src/main/java/com/mzh/library/filter/AuthorizationFilter.java`
|
||||
* `src/main/java/com/mzh/library/entity/Permission.java`
|
||||
* Existing book/auth service and check classes under `src/main/java` and `src/test/java`.
|
||||
* Reader-management implementation should reuse:
|
||||
* `Permission.MANAGE_READERS`
|
||||
* Existing service result and DAO exception patterns
|
||||
* Existing book-module controller/JSP/check structure as the closest local pattern
|
||||
* Final verification notes:
|
||||
* `trellis-implement` completed the reader-management slice across schema, DAO, service, servlet, JSP, CSS, README, spec, and checks.
|
||||
* `trellis-check` fixed a phone-validation gap and added service assertions for missing contact, symbol-only phone, and DAO fallback on write paths.
|
||||
* Available fallback Java compile and service checks passed.
|
||||
* `mvn clean package` remains blocked because Maven is not installed in this environment and local servlet/JSTL jars were not available.
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"id": "continue-program",
|
||||
"name": "continue-program",
|
||||
"title": "brainstorm: 继续完成程序",
|
||||
"description": "",
|
||||
"status": "in_progress",
|
||||
"dev_type": null,
|
||||
"scope": null,
|
||||
"package": null,
|
||||
"priority": "P2",
|
||||
"creator": "Zzzz",
|
||||
"assignee": "Zzzz",
|
||||
"createdAt": "2026-04-27",
|
||||
"completedAt": null,
|
||||
"branch": null,
|
||||
"base_branch": "master",
|
||||
"worktree_path": null,
|
||||
"commit": null,
|
||||
"pr_url": null,
|
||||
"subtasks": [],
|
||||
"children": [],
|
||||
"parent": null,
|
||||
"relatedFiles": [],
|
||||
"notes": "",
|
||||
"meta": {}
|
||||
}
|
||||
Reference in New Issue
Block a user