feat(feedback): admin detail subpage + respond + archive/restore #107
No reviewers
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
psa-systems/bunyip!107
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/feedback-admin-detail-and-archive"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes BUNYIP-85. Second of three feedback parity PRs. Stacks on BUNYIP-84.
bunyip-api already implements every backend behaviour:
GET /v1/admin/feedback/{id}(handlers/feedback.rs:346-358)POST /v1/admin/feedback/{id}/respond(handlers/feedback.rs:361-426; sends email server-side)GET /v1/admin/feedback/archive(handlers/feedback.rs:545-558)POST /v1/admin/feedback/archive/{archive_id}/restore(handlers/feedback.rs:560-581)bunyip-web exposed none of them. Admins could see the row list and toggle status, but not read the full message, send a response, or work the archive.
Changes:
bunyip-web/src/api/types.rs: addArchivedFeedbackmirroring the API'sArchivedFeedbackItem. Addresponded_at: Option<String>(serde-default for rolling deploys) toAdminFeedbackDetailso the detail view can show when a response was sent.bunyip-web/src/api/admin.rs: four new helpers -feedback_detail,respond_to_feedback(POST{response, status: "responded"}JSON),feedback_archive,restore_feedback.bunyip-web/src/handlers/admin.rs:feedback_detail(GET/admin/feedback/:id) renders the detail view: unmasked email, full message (whitespace-pre-wrap),page_path, tags, current status, and EITHER an inline response form OR the existing admin response with its responded-at relative time.feedback_respond(POST/admin/feedback/:id/respond) validates non-empty, calls the API helper, redirects back to the detail page with?toast_ok=Response%20sent/?toast_err=…so the existing toast plumbing renders the confirmation.feedback_archive(GET/admin/feedback/:archive) paginates the archive with Restore buttons per row, sharing the same tab nav.feedback_restore(POST/admin/feedback/archive/:archive_id/restore) calls the API and redirects back to the archive page with a toast.bunyip-web/src/main.rs: register the four new routes. Archive routes register BEFORE the:iddetail route so axum's matcher does not interpret the literalarchiveas a feedback id.Attachments rendering on the detail page is intentionally deferred to BUNYIP-86 alongside the multipart-form-upload work, so the admin UX and the file-upload transport change ship as separate PRs.
just check-containerclean (modulo the pre-existingtest_config_defaultsparallel-env-var flake onmain; 188 other tests pass; fmt + clippy + build clean).#BUNYIP-85
Closes BUNYIP-85. Second of three feedback parity PRs. Stacks on BUNYIP-84. bunyip-api already implements every backend behaviour: - `GET /v1/admin/feedback/{id}` (handlers/feedback.rs:346-358) - `POST /v1/admin/feedback/{id}/respond` (handlers/feedback.rs:361-426; sends email server-side) - `GET /v1/admin/feedback/archive` (handlers/feedback.rs:545-558) - `POST /v1/admin/feedback/archive/{archive_id}/restore` (handlers/feedback.rs:560-581) bunyip-web exposed none of them. Admins could see the row list and toggle status, but not read the full message, send a response, or work the archive. Changes: - `bunyip-web/src/api/types.rs`: add `ArchivedFeedback` mirroring the API's `ArchivedFeedbackItem`. Add `responded_at: Option<String>` (serde-default for rolling deploys) to `AdminFeedbackDetail` so the detail view can show when a response was sent. - `bunyip-web/src/api/admin.rs`: four new helpers - `feedback_detail`, `respond_to_feedback` (POST `{response, status: "responded"}` JSON), `feedback_archive`, `restore_feedback`. - `bunyip-web/src/handlers/admin.rs`: - Existing feedback list grows an "Active / Archive" tab pair above the list; subject in each row becomes a link to the new detail subpage. - `feedback_detail` (GET `/admin/feedback/:id`) renders the detail view: unmasked email, full message (whitespace-pre-wrap), `page_path`, tags, current status, and EITHER an inline response form OR the existing admin response with its responded-at relative time. - `feedback_respond` (POST `/admin/feedback/:id/respond`) validates non-empty, calls the API helper, redirects back to the detail page with `?toast_ok=Response%20sent` / `?toast_err=…` so the existing toast plumbing renders the confirmation. - `feedback_archive` (GET `/admin/feedback/:archive`) paginates the archive with Restore buttons per row, sharing the same tab nav. - `feedback_restore` (POST `/admin/feedback/archive/:archive_id/restore`) calls the API and redirects back to the archive page with a toast. - `bunyip-web/src/main.rs`: register the four new routes. Archive routes register BEFORE the `:id` detail route so axum's matcher does not interpret the literal `archive` as a feedback id. Attachments rendering on the detail page is intentionally deferred to BUNYIP-86 alongside the multipart-form-upload work, so the admin UX and the file-upload transport change ship as separate PRs. `just check-container` clean (modulo the pre-existing `test_config_defaults` parallel-env-var flake on `main`; 188 other tests pass; fmt + clippy + build clean). #BUNYIP-85