Repository navigation
feat: add thread archiving, unread filters, and pagination - #1025
Conversation
|
@greptileai review |
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 215 |
| Duplication | 28 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
[Medium impact] The changes appear safe to merge; no new blocking issues were found. SummaryAdds per-phone outgoing conversation archiving, server-side Unread filters, and 20-conversation pages.
Diagram%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Open conversation] --> B{Already loaded?}
B -->|Yes| E[Load messages]
B -->|No| C[Fetch conversation by ID]
C --> D[Restore phone and archive view]
D --> E
F[Choose All or Unread] --> G[Fetch filtered 20-row pages]
G --> H{Last page full?}
H -->|Yes| I[Show Load More]
H -->|No| J[Hide Load More]
Reviews (6) · Last reviewed commit: "refactor: apply local thread lookup edit..." · Reviewed by Greptile |
There was a problem hiding this comment.
🟡 Changes recommended
Phone creation drops the archive preference, and unread conversation handling has unresolved navigation, refresh, and polling consistency issues.
4 open issues
1 file not reviewed
api/docs/docs.go: Generated file
What changed in this PR
This PR adds per-phone automatic archiving for new outgoing conversations and server-side unread filtering to httpSMS, with frontend controls and regression coverage.
Changes:
- Add the archive preference across phone settings, API models, persistence, and thread creation.
- Add All/Unread filters, selected-conversation retention, and stale list-response protection.
- Expand tests and update frontend typing, styles, and login badge visibility.
| File | Description |
|---|---|
| web/tsconfig.json | Use Nuxt-generated TypeScript project configuration. |
| web/shared/types/api.ts | Add archive-setting types and refresh generated documentation. |
| web/package.json | Add vue-tsc for frontend type checking. |
| web/nuxt.config.ts | Register phone-input styles globally. |
| web/app/utils/errors.ts | Use typed entry iteration for errors. |
| web/app/utils/bag.ts | Use typed entry iteration for collections. |
| web/app/stores/threads.ts | Add unread filtering and selected-thread retention. |
| web/app/stores/threads.test.ts | Test filtering, retention, and stale responses. |
| web/app/stores/phones.ts | Include the archive preference in updates. |
| web/app/stores/app.ts | Use inferred runtime configuration types. |
| web/app/plugins/vPhoneInput.client.ts | Remove the relocated stylesheet import. |
| web/app/pages/settings/index.vue | Add the archive-setting switch and explanation. |
| web/app/pages/search-messages/index.vue | Adjust error iteration for type safety. |
| web/app/pages/phone-api-keys/index.vue | Adjust error iteration for type safety. |
| web/app/pages/index.vue | Read message counts from existing display labels. |
| web/app/pages/bulk-messages/index.vue | Tighten error and filename handling types. |
| web/app/layouts/default.vue | Keep threads scrollable below the taller header. |
| web/app/composables/useApi.ts | Infer the API fetch wrapper’s return type. |
| web/app/components/MessageThreadHeader.vue | Add All/Unread filter controls. |
| web/app/components/MessageThread.vue | Render filtered threads and unread empty state. |
| web/app/components/FirebaseAuth.vue | Prevent Last Used badge clipping. |
| tests/unread_filter_integration_test.go | Test unread filtering, pagination, and validation. |
| tests/unarchive_thread_integration_test.go | Expose unread counts in test responses. |
| tests/archive_new_outgoing_message_threads_integration_test.go | Test archive preferences and reply behavior. |
| api/pkg/validators/message_thread_handler_validator.go | Validate the unread filter. |
| api/pkg/services/phone_service.go | Apply archive preferences during phone updates. |
| api/pkg/services/phone_service_test.go | Test archive-setting update semantics. |
| api/pkg/services/message_thread_service.go | Apply archiving on creation and forward unread filtering. |
| api/pkg/services/message_thread_service_test.go | Test creation rules and existing-thread behavior. |
| api/pkg/services/message_thread_service_contacts_test.go | Update repository stubs for unread filtering. |
| api/pkg/requests/phone_update_request.go | Preserve archive-setting field presence. |
| api/pkg/requests/phone_update_request_test.go | Test enabled, disabled, and omitted values. |
| api/pkg/requests/message_thread_index_request.go | Parse and default the unread filter. |
| api/pkg/repositories/message_thread_repository.go | Extend the thread-list interface. |
| api/pkg/repositories/gorm_message_thread_repository.go | Apply unread filtering before pagination. |
| api/pkg/repositories/gorm_message_thread_repository_test.go | Verify unread query construction. |
| api/pkg/listeners/read_receipts_test_helpers_test.go | Update the repository test helper signature. |
| api/pkg/handlers/message_thread_handler.go | Document the unread query parameter. |
| api/pkg/handlers/message_thread_handler_test.go | Update the repository stub signature. |
| api/pkg/handlers/message_thread_handler_contacts_test.go | Test unread query forwarding and rejection. |
| api/pkg/entities/phone.go | Add the default-off archive preference. |
| api/docs/swagger.yaml | Publish updated API schemas and query documentation. |
| api/docs/swagger.json | Publish updated API schemas and query documentation. |
| api/docs/docs.go | Refresh embedded Swagger documentation. |
Review effort: Balanced
|
@greptileai review |
Add per-phone outgoing archiving and server-side unread filtering. Include integration coverage, frontend type fixes, and login badge fixes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aad7909a-5c34-42df-a4d2-ae6c83c22e7b
|
@greptileai review |
Persist the supplied outgoing-thread archive setting on first registration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aad7909a-5c34-42df-a4d2-ae6c83c22e7b
Apply saved contact metadata when Unread excludes the open conversation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aad7909a-5c34-42df-a4d2-ae6c83c22e7b
Refresh polls overlapping read mutations and retain scoped conversation history. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aad7909a-5c34-42df-a4d2-ae6c83c22e7b
Increment send attempts atomically without overwriting concurrently scheduled state. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aad7909a-5c34-42df-a4d2-ae6c83c22e7b
Load 20 threads per page with server look-ahead and stable pagination ordering. Preserve loaded pages across polling and reset pagination when filters change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aad7909a-5c34-42df-a4d2-ae6c83c22e7b
Resolve conversations independently of paging and restore phone/archive context. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aad7909a-5c34-42df-a4d2-ae6c83c22e7b
|
@greptileai review |
Remove has_more response metadata and internal extra-row look-ahead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aad7909a-5c34-42df-a4d2-ae6c83c22e7b
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aad7909a-5c34-42df-a4d2-ae6c83c22e7b
Log the phone lookup failure and continue saving the unarchived thread. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aad7909a-5c34-42df-a4d2-ae6c83c22e7b
|
@greptileai review Pagination is intentionally count-based per the requested design: no has_more field and no extra-row look-ahead. A full page may leave Load More visible until a shorter or empty page is fetched. |
Remove the phone-specific read check and adjust cancellation wording. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aad7909a-5c34-42df-a4d2-ae6c83c22e7b
|
@greptileai review |

Summary
Behavior and scope
Use
ArchiveNewOutgoingMessageThreadsin Go andarchive_new_outgoing_message_threadsfor JSON and the database column.Archive only newly created outgoing conversations when the phone setting is enabled. Incoming conversations and existing conversations are unaffected.
Keep reply behavior controlled by the existing independent
unarchive_threadsetting.Filter unread conversations on the server before pagination, scoped to the selected phone and inbox/archive view.
Remove conversations from Unread when marked read without interrupting the open conversation. Ignore stale polling responses after filter changes.
Keep the thread list scrollable with the taller header.
Retain strict type checking, add
vue-tsc, and use Nuxt's generated TypeScript project configuration.Deep links resolve individual conversations independently of pagination, including older/archived records and phone selection.
Pagination now uses only returned page counts: no has_more response field or extra-row fetch. A full page keeps Load More available until a shorter or empty page is returned.
The atomic message updater is named IncreaseSendAttemptCount. Phone lookup errors are warned and new conversations default to unarchived without failing creation.
Validation
go test ./...andgo vet ./....pnpm exec nuxt typecheck,pnpm test(64 tests), production build, and lint/format checks for changed files.Deployment verification
The Firebase deployer was granted the missing read-only Service Usage Viewer role. Re-running the failed deployment for unchanged main succeeded: https://github.com/NdoleStudio/httpsms/actions/runs/39730796417