Feature/issue 1072 1073 1074 1075 - #1181
Merged
Xoulomon merged 5 commits intoSep 1, 2026
Merged
Conversation
added 4 commits
August 28, 2026 14:44
… submodules (Xoulomon#1075) The monolithic contracts.rs was a merge-conflict hotspot. Route handlers are now split into focused resource modules under backend/src/api/contracts/. New files --------- backend/src/api/mod.rs Top-level API module; mounts all sub-APIs under /api. backend/src/api/contracts/mod.rs Re-exports waste and incentive submodules; mounts both under /api/contracts. backend/src/api/contracts/waste.rs (~250 lines) Handlers: register_waste, get_waste, list_participant_wastes, transfer_waste, update_waste_status. Route scope: /api/contracts/waste/** Integration tests for success, missing fields, invalid status values, and self-transfer rejection. backend/src/api/contracts/incentive.rs (~220 lines) Handlers: distribute_rewards, get_balance, claim_reward, list_programmes. Route scope: /api/contracts/incentive/** Integration tests for success, zero amounts, missing wallet, and programme listing. backend/src/api/errors.rs Shared ApiError type used by all handlers (see also Xoulomon#1073 commit). Modified files -------------- backend/src/main.rs Add 'mod api;' and wire configure_api_routes into the App builder. Replace println! startup log with log::info! (Xoulomon#1074 logging convention).
…Xoulomon#1074) Define and apply a consistent structured-logging convention to every service in backend/src/services. Logging convention (see docs/LOGGING_CONVENTION.md) --------------------------------------------------- Every log call emits at minimum three key-value fields: service — module name (e.g. 'notifications') op — method name (e.g. 'register_device') outcome — 'ok' | 'error' | 'warn' These fields make every log line queryable in Grafana/Loki via: {app='scavenger-backend'} | json | service='notifications', outcome='error' Changes per service ------------------- notifications.rs - Added log::info! on successful register_device, get_preferences, set_preferences, schedule_notification. - Added log::warn! for all validation/guard rejections. - Added log::error! for FCM HTTP failures with status code. - Removed implicit println!/debug output. reporting.rs - Added log::info! on generate_report, get_report, schedule_report, get_templates, cache_report success paths. - Added log::warn! for all InvalidReport / NotFound early returns. - Includes recipient_count and bytes context where useful. storage.rs - Added log::info! on upload_file (with bytes), delete_file, get_signed_url, get_file_metadata success paths. - Added log::warn! for every empty-id / zero-expiration guard. email.rs - Added log::info! on successful send_transactional, send_digest, add_to_unsubscribe_list, is_unsubscribed. - Added log::warn! for validation failures. - Added log::error! for SendGrid HTTP failures with status code. - Added email_domain() helper to log domain only (PII reduction). - Removed println!/eprintln! left over from development. main.rs (updated in Xoulomon#1075 commit) - println! startup message replaced with log::info!. New file -------- docs/LOGGING_CONVENTION.md - Documents required fields (service, op, outcome). - Documents optional fields (request_id, user_id, error, bytes). - Documents log-level guidance and PII rules. - Includes Grafana/Loki LogQL query examples. - Lists banned patterns (println!, unstructured log::info!).
Xoulomon#1073) All API modules now return Result<_, ApiError> so the client always receives the same JSON error envelope regardless of which module raised the error. New files --------- backend/src/errors.rs Re-exports ApiError, ErrorBody, ErrorDetail from api::errors (the type definition lives there; this module is the canonical import path: 'use crate::errors::ApiError'). Adds From<ServiceError> for ApiError for all four service error enums: ReportError::InvalidReport → ApiError::Validation (400) ReportError::NotFound → ApiError::NotFound (404) ReportError::ServiceError → ApiError::Internal (500) StorageError::InvalidFile → ApiError::Validation (400) StorageError::NotFound → ApiError::NotFound (404) StorageError::ServiceError → ApiError::Internal (500) NotificationError::Invalid → ApiError::Validation (400) NotificationError::NotFound → ApiError::NotFound (404) NotificationError::Service → ApiError::Internal (500) EmailError::InvalidEmail → ApiError::Validation (400) EmailError::TemplateError → ApiError::Internal (500) EmailError::ServiceError → ApiError::Internal (500) Integration tests assert the exact wire-format shape consistency: - every variant produces { error: { code, message, request_id } } - no extra top-level keys are present - HTTP status codes match for all six variants - all service-error conversions produce the correct ApiError code docs/ERROR_HANDLING.md Documents the canonical error type, wire format, HTTP status mapping, service error mapping table, and usage patterns. Lists explicitly banned patterns (ad-hoc JSON construction, bare actix_web::Error, panic!/unwrap() in handlers). Modified files -------------- backend/src/main.rs Add 'mod errors;' declaration so the module is compiled and its From impls are available crate-wide. Context ------- The ApiError type and its ResponseError implementation were introduced in Xoulomon#1075 (backend/src/api/errors.rs). This commit adds the canonical top-level re-export path, wires all service-error conversions, and provides the integration tests required by issue Xoulomon#1073.
…eExport and useImport (Xoulomon#1072) Audit of frontend/src/hooks/useExportImport.ts call sites confirmed that only CSV and JSON formats are actively used. All dead branches have been removed and the hook has been split into two focused modules. Dead code removed ----------------- The original combined hook contained format-handling branches with no call sites in the codebase: - XML export/import handler - XLS / XLSX export/import handler - 'legacy-csv' branch with a different column order (superseded by the current CSV path in useAnalyticsExport) - Unreachable 'dry-run preview' branch never wired to any UI component New files --------- frontend/src/hooks/useExport.ts Provides exportToCSV(rows, options?) and exportToJSON(data, options?). Both functions are stable useCallback references. Supported formats: CSV (text/csv) and JSON (application/json). Optional filename override; falls back to 'export-<timestamp>.<ext>'. frontend/src/hooks/useImport.ts Provides importFromCSV(file) and importFromJSON(file). Exposes an ImportState<T> { data, error, isLoading } alongside the async functions so callers can drive UI feedback from a single hook. Supported formats: CSV (parsed into CsvRecord[] header-keyed objects) and JSON (parsed into typed T via JSON.parse). frontend/src/hooks/useExportImport.ts (updated) Now a thin re-export barrel for backward compatibility. Documents which dead branches were removed. New code should import directly from useExport or useImport. Test files (new) ---------------- frontend/src/hooks/__tests__/useExport.test.ts (15 tests) - CSV: triggers download, correct MIME type, custom filename, timestamped fallback filename, empty-rows guard (no download), stable callback reference across re-renders. - JSON: triggers download, correct MIME type, custom filename, timestamped fallback, array data, stable reference. - Dead-branch assertions: exportToXML, exportToXLS, exportToXLSX, exportToLegacyCSV are all undefined on the returned object. frontend/src/hooks/__tests__/useImport.test.ts (15 tests) - CSV: parses header-keyed records, state.data set, error on empty file, isLoading lifecycle, FileReader failure, header-only CSV, blank-line skipping. - JSON: parses object/array, state.data set, error on invalid JSON. - Dead-branch assertions: importFromXML, importFromXLS, importFromXLSX, dryRunPreview, previewImport are all undefined on the returned object.
|
@Pilot39 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Type of Change
Testing
cargo test/npm test)Review Checklist
Related Issues
Closes #1075
Closes #1074
Closes #1073
Closes #1072