Full plan for completing all pending features across backend, frontend, and admin. Includes Beeceptor mock payment endpoints, Wave 1-5 breakdown, file-level implementation details, and parallelization strategy. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
10 KiB
Nxtgauge — Work Implementation Roadmap (wir.md)
Beeceptor Mock Payment Gateway
- Base URL:
https://nxtgauge.free.beeceptor.com POST /payments/create-order→ 200POST /payments/verify→ 200GET /payments/:id/status→ 200
Wave 1 — Foundation Fixes (Must do first)
W1-A: Fix AppState type alias in all profession services
Every admin.rs uses crate::AppState but main.rs never defines it. Add after use contracts::ProfessionState;:
type AppState = ProfessionState;
Files to modify:
apps/photographers/src/main.rsapps/makeup_artists/src/main.rsapps/tutors/src/main.rsapps/developers/src/main.rsapps/video_editors/src/main.rsapps/graphic_designers/src/main.rsapps/social_media_managers/src/main.rsapps/fitness_trainers/src/main.rsapps/catering_services/src/main.rs
W1-B: Fix employee create endpoint mismatch
Admin UI POSTs to /api/admin/employees/provision but backend registers POST /.
- File:
apps/employees/src/handlers/employees.rs - Add:
.route("/provision", post(create_employee))alias
W1-C: Gateway routing for missing admin namespaces
File: apps/gateway/src/main.rs — add to resolve_upstream:
- Add
|| path.starts_with("/api/admin/ugc-content-creators")to UGC branch - Route
admin/tax,admin/ledger,admin/orders→ payments service
Wave 2 — Backend Features (parallel after Wave 1)
W2-A: Suspend/activate for all 9 professions + UGC
Add PATCH /{id}/status to each profession admin.rs:
.route("/{id}/status", patch(set_status))
async fn set_status(
State(state): State<AppState>,
Path(id): Path<Uuid>,
Json(body): Json<StatusPayload>,
) -> impl IntoResponse {
// 1. Query user_id from profession table WHERE id = $1
// 2. UPDATE users SET status = $1 WHERE id = $2
// 3. Return 200 or error
}
#[derive(Deserialize)]
struct StatusPayload { status: String } // "ACTIVE" | "INACTIVE" | "SUSPENDED"
Uses existing UserRepository::update_status.
W2-B: UGC full admin module (currently zero admin routes)
- Create:
apps/ugc_content_creators/src/admin.rs(copy photographers pattern, adapt table name) - Modify:
apps/ugc_content_creators/src/main.rs— addmod admin;and.nest("/api/admin/ugc-content-creators", admin::router()) - Use
Router<ProfessionState>directly (nocrate::AppStatealias needed)
W2-C: Backend endpoints for tax, ledger, orders
Add to apps/payments/src/main.rs (or new apps/payments/src/admin.rs):
GET /api/admin/tax,POST /api/admin/tax,DELETE /api/admin/tax/{id}— CRUD againsttaxestableGET /api/admin/ledger— querytracecoin_ledgerJOIN users, paginatedGET /api/admin/orders— query payments/orders table
Also add GET /api/admin/credits/reconcile-report and POST /api/admin/credits/reconcile/{order_id} for W4-F.
Wave 3 — Frontend Dashboard Pages (parallel after Wave 1, biggest work)
Architecture
- Add all new page names to
REAL_PAGESindashboard.tsx - Add
<Match>cases in the<Switch>block - Pass
rolePrefixfromROLE_PREFIXES[role()] - Add
'Accepted Leads'and'Services'toROLE_BASED_SIDEBARfor all 10 professional roles - Update
ICON_MAPinDashboardShell.tsx
W3-A: Professional pages (shared by all 10 professions via rolePrefix prop)
File: src/components/dashboard/LeadsMarketplacePage.tsx
GET /api/{rolePrefix}/marketplace?page=N&limit=20- Paginated requirement cards: title, budget, location, deadline, profession category
- "Send Request" →
POST /api/{rolePrefix}/leads/requestwith{ requirement_id }
File: src/components/dashboard/MyRequestsPage.tsx
GET /api/{rolePrefix}/leads/requests/me- Status badges: PENDING, ACCEPTED, REJECTED, CANCELLED
- 24h countdown from
created_atfor PENDING requests - Cancel →
DELETE /api/{rolePrefix}/leads/requests/{id}
File: src/components/dashboard/AcceptedLeadsPage.tsx
GET /api/{rolePrefix}/leads/accepted/me- Customer contact info revealed (phone, email)
- Detail →
GET /api/{rolePrefix}/leads/accepted/{id}
File: src/components/dashboard/CreditsWalletPage.tsx
GET /api/{rolePrefix}/wallet/me→ balance summary (total, reserved, available)GET /api/{rolePrefix}/wallet/me/ledger?page=1&limit=20→ transaction history- Buy TraceCoins flow (Beeceptor):
- Show package selection
POST https://nxtgauge.free.beeceptor.com/payments/create-orderPOST https://nxtgauge.free.beeceptor.com/payments/verify- Refresh wallet balance on success
File: src/components/dashboard/ServicesPage.tsx
GET /api/{rolePrefix}/services/me— list services- Add:
POST /api/{rolePrefix}/services/me - Edit:
PATCH /api/{rolePrefix}/services/me/{id}(add toapi.ts) - Delete:
DELETE /api/{rolePrefix}/services/me/{id}
Shared: src/components/dashboard/BuyTracecoinsModal.tsx
- Reusable modal used by CreditsWalletPage and CustomerRequirementsPage
- Calls Beeceptor: create-order → verify
- Props:
{ rolePrefix: string; onSuccess: () => void; onClose: () => void }
W3-B: Company pages
File: src/components/dashboard/CompanyJobsPage.tsx
GET /api/companies/jobs— list with status badges (DRAFT, PENDING, APPROVED, CLOSED)- Create form →
POST /api/companies/jobs - Submit for approval →
POST /api/companies/jobs/{id}/submit
File: src/components/dashboard/CompanyApplicationsPage.tsx
- Job selector dropdown
GET /api/companies/jobs/{id}/applications- Status update →
PATCH /api/companies/applications/{id}/status
W3-C: Job Seeker pages
File: src/components/dashboard/JobSeekerJobsPage.tsx
GET /api/jobseeker/jobs?page=N&limit=20with filters- Apply modal →
POST /api/jobseeker/jobs/{id}/apply
File: src/components/dashboard/JobSeekerApplicationsPage.tsx
GET /api/jobseeker/applications- Status badges, withdraw →
DELETE /api/jobseeker/applications/{id}/withdraw(add toapi.ts)
W3-D: Customer pages
File: src/components/dashboard/CustomerRequirementsPage.tsx
GET /api/customers/requirements— list with expiry countdown- Create form →
POST /api/customers/requirements - Submit →
POST /api/customers/requirements/{id}/submit
File: src/components/dashboard/ReceivedResponsesPage.tsx
- Requirement selector at top
GET /api/customers/requirements/{id}/requests- Accept →
POST /api/customers/requirements/{id}/requests/{lead_id}/approve - Reject →
POST /api/customers/requirements/{id}/requests/{lead_id}/reject
W3-E: Explore Nxtgauge + Switch Services
File: src/components/dashboard/ExploreNxtgaugePage.tsx
- Extract from DashboardDesignPreview (lines ~5920–5990)
- Props:
{ roleKey: string; rolePrefix: string; exploreRoles: Array<{key: string; name: string}> } - Switch Services → same component or redirect to Explore Nxtgauge
Wave 4 — Admin Completions (parallel with Wave 3)
W4-A: Verification action wiring
File: src/routes/admin/verification.tsx
Wire existing stub handlers:
- Approve:
POST /api/gateway/api/admin/verifications/{id}/approve - Reject:
POST /api/gateway/api/admin/verifications/{id}/reject+{ reason: string } - Request Docs:
POST /api/gateway/api/admin/verifications/{id}/request-documents+{ message, documents[] } - Refresh list after each action
W4-B: Employee create — resolve by email
File: src/routes/admin/employees/create.tsx
Two-step flow:
- Email lookup →
GET /api/admin/users?email={email} - If found: pre-fill name, show confirmation
- If not: allow new user creation
- Submit with
user_idfrom resolved user (or usePOST /api/admin/employees/provision)
W4-C: Admin Ledger
File: src/routes/admin/ledger.tsx
- Needs W2-C backend first
- Add: user filter, date range filter, entry type filter, pagination
W4-D: Tax management
File: src/routes/admin/tax.tsx — UI already complete
- Just needs W1-C (gateway routing) + W2-C (backend endpoint)
W4-E: Order management
File: src/routes/admin/order.tsx — UI already complete
- Just needs W1-C + W2-C
W4-F: Credit reconciliation
File: src/routes/admin/financial/reconcile.tsx — currently a redirect stub
- Needs W2-C backend endpoint
- Build reconciliation view: orders vs. coins credited discrepancies
- "Reconcile" action →
POST /api/admin/credits/reconcile/{order_id}
Wave 5 — Token Security (independent, any time)
W5-A: Move access token to in-memory
File: src/lib/auth.tsx
let _token: string | null = null;
export const setToken = (t: string | null) => { _token = t; };
export const getToken = (): string | null =>
_token || sessionStorage.getItem('nxtgauge_access_token') || localStorage.getItem('nxtgauge_access_token') || null;
File: src/lib/api.ts
- Update
getAuthHeaders()to usegetToken()from auth.tsx
New Files to Create
Backend
apps/ugc_content_creators/src/admin.rs
Frontend
src/components/dashboard/LeadsMarketplacePage.tsxsrc/components/dashboard/MyRequestsPage.tsxsrc/components/dashboard/AcceptedLeadsPage.tsxsrc/components/dashboard/CreditsWalletPage.tsxsrc/components/dashboard/ServicesPage.tsxsrc/components/dashboard/BuyTracecoinsModal.tsxsrc/components/dashboard/CompanyJobsPage.tsxsrc/components/dashboard/CompanyApplicationsPage.tsxsrc/components/dashboard/JobSeekerJobsPage.tsxsrc/components/dashboard/JobSeekerApplicationsPage.tsxsrc/components/dashboard/CustomerRequirementsPage.tsxsrc/components/dashboard/ReceivedResponsesPage.tsxsrc/components/dashboard/ExploreNxtgaugePage.tsx
Files to Modify
Backend
apps/gateway/src/main.rs— W1-Capps/employees/src/handlers/employees.rs— W1-Bapps/photographers/src/main.rs+ all 8 other profession main.rs — W1-Aapps/ugc_content_creators/src/main.rs— W2-B- All 9 profession
admin.rsfiles — W2-A apps/payments/src/main.rs(or newpayments/src/admin.rs) — W2-C
Frontend
src/routes/dashboard.tsx— expand REAL_PAGES + add Match cases + update ROLE_BASED_SIDEBARsrc/components/DashboardShell.tsx— update ICON_MAPsrc/lib/auth.tsx— W5-Asrc/lib/api.ts— add updateService, withdrawApplication helpers + W5-A
Admin
src/routes/admin/verification.tsx— W4-Asrc/routes/admin/employees/create.tsx— W4-Bsrc/routes/admin/ledger.tsx— W4-Csrc/routes/admin/financial/reconcile.tsx— W4-F