3.5 KiB
3.5 KiB
Agent 1 — Batch 2 Implementation Report
Task
Implement POST /api/content/:cxid/report in crates/cgcx-server/src/main.rs.
Changes Made
1. crates/cgcx-server/Cargo.toml
- Added dependency:
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
2. crates/cgcx-server/src/main.rs
- Imports: Added
ReportRepoto thecgcx_dbimport list. - AppState: Added
http_client: reqwest::Clientfield. - Main initialization: Created
reqwest::Client::new()and included it inAppState. - Route: Added
.route("/api/content/:cxid/report", post(report_content))to the main router.- The route is automatically covered by the existing
tower_governor::GovernorLayerapplied to the whole app.
- The route is automatically covered by the existing
- Structs:
- Added
ReportRequest { reason: String }for JSON deserialization.
- Added
- Handler
report_content:- Parses
cxidfrom path parameter. - Looks up content via
ContentRepo::get; returns404 Not Foundif missing. - Validates content is active (not
DeletedorBlacklisted); returns404otherwise. - Counts associated files via
ContentFileRepo::list_by_content. - Inserts a report row via
ReportRepo::insertwithreporter_user_id = 0. - Constructs an HTML notification message matching the bot’s report format:
<b>[ NEW REPORT ]</b> #{report_id} CXID: <code>{cxid}</code> Reporter: <i>web</i> Owner: <code>{content.user_id}</code> Uploaded: <i>{content.created_at}</i> Files: <b>{file_count}</b> - Sends the message to all configured
review_group_idsvia direct HTTPSPOSTto the Telegram Bot API ({api_base}/bot{token}/sendMessage). - Includes an inline keyboard with the same admin actions as bot reports:
[ Rmv + Ban ]→v1:admin:delblk:{report_id}[ Delete Only ]→v1:admin:del:{report_id}[ Blacklist Only ]→v1:admin:blk:{report_id}[ Ignore ]→v1:admin:ign:{report_id}
- If any HTTPS call fails, logs a
tracing::warnbut does not fail the HTTP request. - Returns
204 No Contenton success.
- Parses
Validation
cargo check -p cgcx-server— PASSED (clean compile, no warnings).- The router merge order places the new route inside the same
Routerthat gets the general governor layer, so rate limiting applies automatically.
Open Risks / Notes
- Foreign Key for
reporter_user_id = 0: Thereportstable hasFOREIGN KEY (reporter_user_id) REFERENCES users(id). If SQLitePRAGMA foreign_keys = ONis active and no user withid = 0exists, the insert will fail with a database error (returned as500 Internal Server Error). This matches the explicit instruction to use0for web submissions, but the project may need a dummy user row or a schema adjustment if this becomes an issue in production. - Telegram API failures are non-blocking: As required, a failed notification is only logged; the caller still receives
204. This means review groups could miss reports if the network or Telegram API is down. - No dedicated rate limit for reports: The endpoint shares the general API rate-limit bucket. If high report volume is expected, a separate governor config (like the password route) could be considered later.
Recommended Next Step
- Verify the frontend report submission flow end-to-end against the new endpoint.
- Optionally seed a user with
id = 0(or relax the FK) if web reports trigger foreign-key violations.
Date: 2026-05-24