Feature Inventory
Status legend: ✅ fully wired · ⚠️ partially wired · ❌ not wired
Source of truth: backend controllers in apps/backend/src/, mobile screens in apps/mobile/src/screens/, admin pages in apps/admin/src/pages/. Endpoints below are relative to /api/v1.
Auth
| Feature | Endpoint(s) | Client | Status |
|---|---|---|---|
| Register (email + password + name) | POST /auth/register | authApi.register (mobile) → RegisterScreen | ✅ |
| Login | POST /auth/login | authApi.login (mobile) → LoginScreen; POST /admin/auth/login (admin) → LoginPage | ✅ |
| Refresh token | POST /auth/refresh, POST /admin/auth/refresh | authApi.refresh (mobile), admin api.ts interceptor | ✅ |
| Logout | POST /auth/logout | authApi.logout (mobile, via AuthContext) | ✅ |
| Fetch current user | GET /auth/me | authApi.getMe (mobile, via AuthContext) | ✅ |
| Verify email (token from email) | POST /auth/verify-email | authApi.verifyEmail — no dedicated screen yet | ⚠️ (client wrapped, no UI) |
| Resend verification email | POST /auth/resend-verification | authApi.resendVerification — no dedicated UI | ⚠️ |
| Forgot password | POST /auth/forgot-password | authApi.forgotPassword — no dedicated screen yet | ⚠️ |
| Reset password (token from email) | POST /auth/reset-password | authApi.resetPassword — no dedicated screen yet | ⚠️ |
Tasks
| Feature | Endpoint(s) | Client | Status |
|---|---|---|---|
| Create task | POST /tasks | tasksApi.create → CreateTaskScreen | ✅ |
| Browse tasks nearby (geo filter) | GET /tasks?longitude&latitude&radiusKm | tasksApi.list → MapScreen | ✅ |
| View task detail | GET /tasks/:id | tasksApi.getById — used by inbox/chat flows | ⚠️ (no standalone detail screen) |
| Edit task | PUT /tasks/:id | tasksApi.update — no UI screen yet | ⚠️ |
| Delete task | DELETE /tasks/:id | tasksApi.remove — no UI action yet | ⚠️ |
| Accept task (helper applies) | POST /tasks/:id/accept | tasksApi.accept — used by interaction flow | ⚠️ |
| Mark task complete (helper) | POST /tasks/:id/complete | tasksApi.complete — no dedicated UI trigger | ⚠️ |
| Confirm completion (creator) | PUT /tasks/:id/confirm | tasksApi.confirm — no dedicated UI trigger | ⚠️ |
| List my posted tasks | GET /users/me/tasks | usersApi.getMyTasks → ProfileScreen | ✅ |
| List tasks I helped with | GET /users/me/helped | usersApi.getMyHelped → ProfileScreen | ✅ |
Interactions (messaging + time proposals)
Every task with an accepted helper opens a TaskInteraction container that owns messages and time-proposal negotiation.
| Feature | Endpoint(s) | Client | Status |
|---|---|---|---|
| Inbox (all my interactions) | GET /users/:userId/interactions | interactionsApi.listUserInteractions → InteractionsInboxScreen | ✅ |
| Task interaction thread | GET /tasks/:taskId/interactions | interactionsApi.listTaskInteractions → ChatScreen | ✅ |
| Send message | POST /tasks/:taskId/messages | interactionsApi.createMessage → ChatScreen | ✅ |
| List messages (paginated) | GET /tasks/:taskId/messages | interactionsApi.listMessages → ChatScreen | ✅ |
| Mark message as read | PATCH /tasks/:taskId/messages/:messageId/read | interactionsApi.markMessageAsRead → ChatScreen | ✅ |
| Create time proposal | POST /tasks/:taskId/time-proposals | interactionsApi.createTimeProposal → TimeProposalScreen | ✅ |
| List time proposals | GET /tasks/:taskId/time-proposals | interactionsApi.listTimeProposals → TimeProposalScreen | ✅ |
| Accept proposal | POST /tasks/:taskId/time-proposals/:proposalId/accept | interactionsApi.acceptTimeProposal → TimeProposalScreen | ✅ |
| Reject proposal | POST /tasks/:taskId/time-proposals/:proposalId/reject | interactionsApi.rejectTimeProposal → TimeProposalScreen | ✅ |
| Counter proposal | POST /tasks/:taskId/time-proposals/:proposalId/counter | interactionsApi.counterTimeProposal → TimeProposalScreen | ✅ |
Points
| Feature | Endpoint(s) | Client | Status |
|---|---|---|---|
| Get balance | GET /users/:userId/points | pointsApi.getBalance → ProfileScreen, RewardsScreen | ✅ |
| Transaction history | GET /users/:userId/points/history | pointsApi.getHistory — no dedicated screen yet | ⚠️ (client wrapped, no UI) |
| Earn on task completion | (server-side, no direct endpoint) | Emitted by TasksService.confirm | ✅ |
Partners & Rewards
| Feature | Endpoint(s) | Client | Status |
|---|---|---|---|
| Browse partners + offers | GET /partners, GET /partners/:id | partnersApi.list, partnersApi.getById → RewardsScreen | ✅ |
| Redeem offer with points | POST /partners/:id/redeem | partnersApi.redeem → RewardsScreen | ✅ |
| List my redemptions | not implemented | — | ❌ (deferred) |
Profiles
| Feature | Endpoint(s) | Client | Status |
|---|---|---|---|
| View own profile | GET /auth/me | authApi.getMe → ProfileScreen | ✅ |
| View public profile | GET /users/:id | usersApi.getById → PublicProfileScreen | ✅ |
| Edit profile (name, bio, avatar) | PUT /users/me | usersApi.updateMe → EditProfileScreen | ✅ |
| Predefined avatar picker | GET /users/avatars | usersApi.getAvatars → EditProfileScreen | ✅ |
Admin panel (apps/admin)
| Feature | Endpoint(s) | Client | Status |
|---|---|---|---|
| Admin login / refresh | POST /admin/auth/login, POST /admin/auth/refresh | admin api.login → LoginPage | ✅ |
| Dashboard stats | GET /admin/stats | api.getStats → Dashboard | ✅ |
| List users (search / filter) | GET /admin/users | api.getUsers → UsersPage | ✅ |
| Verify user (approve/reject inline) | PATCH /admin/users/:id/verify | api — used by admin flow | ✅ |
| Suspend / unsuspend user | PATCH /admin/users/:id/suspend (body { suspended, reason }) | api.suspendUser, api.unsuspendUser → UsersPage (see Spec 003) | ✅ |
| User activities log | GET /admin/users/:id/activities | api — used in user detail | ✅ |
| Verification queue | GET /admin/verifications, POST /admin/verifications/:id/approve, POST /admin/verifications/:id/reject | api.getVerificationRequests, api.approveVerification, api.rejectVerification → VerificationsPage | ✅ |
| Points adjustment | POST /admin/points/adjust | api.adjustPoints → PointsPage | ✅ |
| Points transactions list | GET /admin/points/transactions | api.getPointsTransactions → PointsPage | ✅ |
| Audit logs | GET /admin/audit-logs | api.getAuditLogs → AuditLogsPage | ✅ |
| Partner CRUD | GET/POST/PUT/DELETE /admin/partners, POST/PUT /admin/partners/:id/offers | admin api — CRUD helpers | ⚠️ (backend ready, admin page pending) |
Static / drawer screens (no backend calls)
AboutScreen, FaqScreen, ContactScreen, FeedbackScreen — informational drawer entries. Contact/Feedback have no submission endpoint yet.
Gaps traced to Specs 001–003
Specs 001, 002, and 003 identified the mobile/admin wiring gaps below. All three specs shipped and are marked COMPLETE, so the gaps listed here are closed. They remain in this doc as a reference for anyone auditing older PRs.
| Spec | Original gap | Resolution |
|---|---|---|
| 001 | Only a handful of the 30+ backend endpoints had a mobile client wrapper | apps/mobile/src/services/api.ts now exposes authApi, tasksApi, usersApi, pointsApi, partnersApi, interactionsApi — every endpoint listed above has a typed method |
| 002 | MapScreen, ProfileScreen, RewardsScreen, EditProfileScreen made no API calls | All four now fetch/mutate through the client with loading + error states |
| 003 | Admin called POST /admin/users/:id/unsuspend, which never existed | Both suspend and unsuspend now PATCH /admin/users/:id/suspend with { suspended, reason } |
Remaining ⚠️ entries above are UI-side follow-ups (screens not yet built) — not API gaps.
