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>
265 lines
10 KiB
Markdown
265 lines
10 KiB
Markdown
# Nxtgauge — Work Implementation Roadmap (wir.md)
|
||
|
||
## Beeceptor Mock Payment Gateway
|
||
- **Base URL:** `https://nxtgauge.free.beeceptor.com`
|
||
- `POST /payments/create-order` → 200
|
||
- `POST /payments/verify` → 200
|
||
- `GET /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;`:
|
||
```rust
|
||
type AppState = ProfessionState;
|
||
```
|
||
Files to modify:
|
||
- `apps/photographers/src/main.rs`
|
||
- `apps/makeup_artists/src/main.rs`
|
||
- `apps/tutors/src/main.rs`
|
||
- `apps/developers/src/main.rs`
|
||
- `apps/video_editors/src/main.rs`
|
||
- `apps/graphic_designers/src/main.rs`
|
||
- `apps/social_media_managers/src/main.rs`
|
||
- `apps/fitness_trainers/src/main.rs`
|
||
- `apps/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`:
|
||
1. Add `|| path.starts_with("/api/admin/ugc-content-creators")` to UGC branch
|
||
2. 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`:
|
||
```rust
|
||
.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` — add `mod admin;` and `.nest("/api/admin/ugc-content-creators", admin::router())`
|
||
- Use `Router<ProfessionState>` directly (no `crate::AppState` alias 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 against `taxes` table
|
||
- `GET /api/admin/ledger` — query `tracecoin_ledger` JOIN users, paginated
|
||
- `GET /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_PAGES` in `dashboard.tsx`
|
||
- Add `<Match>` cases in the `<Switch>` block
|
||
- Pass `rolePrefix` from `ROLE_PREFIXES[role()]`
|
||
- Add `'Accepted Leads'` and `'Services'` to `ROLE_BASED_SIDEBAR` for all 10 professional roles
|
||
- Update `ICON_MAP` in `DashboardShell.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/request` with `{ requirement_id }`
|
||
|
||
**File:** `src/components/dashboard/MyRequestsPage.tsx`
|
||
- `GET /api/{rolePrefix}/leads/requests/me`
|
||
- Status badges: PENDING, ACCEPTED, REJECTED, CANCELLED
|
||
- 24h countdown from `created_at` for 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):
|
||
1. Show package selection
|
||
2. `POST https://nxtgauge.free.beeceptor.com/payments/create-order`
|
||
3. `POST https://nxtgauge.free.beeceptor.com/payments/verify`
|
||
4. 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 to `api.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=20` with 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 to `api.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:
|
||
1. Email lookup → `GET /api/admin/users?email={email}`
|
||
2. If found: pre-fill name, show confirmation
|
||
3. If not: allow new user creation
|
||
4. Submit with `user_id` from resolved user (or use `POST /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`
|
||
```typescript
|
||
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 use `getToken()` from auth.tsx
|
||
|
||
---
|
||
|
||
## New Files to Create
|
||
|
||
### Backend
|
||
- `apps/ugc_content_creators/src/admin.rs`
|
||
|
||
### Frontend
|
||
- `src/components/dashboard/LeadsMarketplacePage.tsx`
|
||
- `src/components/dashboard/MyRequestsPage.tsx`
|
||
- `src/components/dashboard/AcceptedLeadsPage.tsx`
|
||
- `src/components/dashboard/CreditsWalletPage.tsx`
|
||
- `src/components/dashboard/ServicesPage.tsx`
|
||
- `src/components/dashboard/BuyTracecoinsModal.tsx`
|
||
- `src/components/dashboard/CompanyJobsPage.tsx`
|
||
- `src/components/dashboard/CompanyApplicationsPage.tsx`
|
||
- `src/components/dashboard/JobSeekerJobsPage.tsx`
|
||
- `src/components/dashboard/JobSeekerApplicationsPage.tsx`
|
||
- `src/components/dashboard/CustomerRequirementsPage.tsx`
|
||
- `src/components/dashboard/ReceivedResponsesPage.tsx`
|
||
- `src/components/dashboard/ExploreNxtgaugePage.tsx`
|
||
|
||
---
|
||
|
||
## Files to Modify
|
||
|
||
### Backend
|
||
- `apps/gateway/src/main.rs` — W1-C
|
||
- `apps/employees/src/handlers/employees.rs` — W1-B
|
||
- `apps/photographers/src/main.rs` + all 8 other profession main.rs — W1-A
|
||
- `apps/ugc_content_creators/src/main.rs` — W2-B
|
||
- All 9 profession `admin.rs` files — W2-A
|
||
- `apps/payments/src/main.rs` (or new `payments/src/admin.rs`) — W2-C
|
||
|
||
### Frontend
|
||
- `src/routes/dashboard.tsx` — expand REAL_PAGES + add Match cases + update ROLE_BASED_SIDEBAR
|
||
- `src/components/DashboardShell.tsx` — update ICON_MAP
|
||
- `src/lib/auth.tsx` — W5-A
|
||
- `src/lib/api.ts` — add updateService, withdrawApplication helpers + W5-A
|
||
|
||
### Admin
|
||
- `src/routes/admin/verification.tsx` — W4-A
|
||
- `src/routes/admin/employees/create.tsx` — W4-B
|
||
- `src/routes/admin/ledger.tsx` — W4-C
|
||
- `src/routes/admin/financial/reconcile.tsx` — W4-F
|