# Handoff Project: `ina-trading-web` Current branch: `main` Latest verified commit: `7e6446b` ## Summary This codebase has recent updates around auth/onboarding, help/privacy pages, dashboard search, product creation/edit/review/detail, admin review/detail, stock/price editing, seller in-review listing, and backend request logging. The latest build was verified successfully with: ```bash npm run build ``` ## Recent Commits - `7e6446b` `Refine seller onboarding and product review flows` - `e9a0cd0` `Update product review, measurement, and backend logging flows` - `b266047` `Fix TypeScript build errors in product detail and admin review` ## Main Changes ### 1. Auth, help, and onboarding Files: - `next.config.ts` - `src/app/(onboarding)/layout.tsx` - `src/app/(auth)/login/page.tsx` - `src/app/(auth)/register/verify/page.tsx` - `src/app/(auth)/forgot-password/page.tsx` - `src/app/(auth)/account-not-found/page.tsx` - `src/app/help/page.tsx` - `src/app/privacy/page.tsx` - `src/app/terms/page.tsx` Behavior: - Seller onboarding is enabled again - Seller login redirects incomplete seller profiles to onboarding - Register verify flow redirects seller to onboarding instead of dashboard - Forgot password support link opens default mail app to `admin@inatrading.co.id` - Forgot password `?` button links to public `/help` - Account-not-found `Bantuan`, `Kebijakan Privasi`, and `Syarat & Ketentuan` link to public pages - Login `Remember me` now stores email and password in localStorage ### 2. Onboarding seller final submit flow Files: - `src/app/(onboarding)/onboarding/business/page.tsx` - `src/app/(onboarding)/onboarding/store-detail/page.tsx` - `src/app/api/seller/route.ts` - `src/app/api/seller/store/route.ts` - `src/app/api/warehouses/route.ts` Behavior: - Plan step was removed from seller onboarding UI flow - `Warehouse Type` is hidden in UI and forced to `INA` - Final onboarding submit is not a single endpoint. It calls, in order: 1. `POST /api/seller` -> host `POST /api/v1.0/seller` 2. `PUT /api/seller/store` -> host `PUT /api/v1.0/seller/store` 3. `GET /api/products/warehouses?page=1&size=100` 4. `PUT /api/warehouses/{id}` or `POST /api/warehouses` - Frontend tries to reuse backend autogenerated warehouse if found, to avoid duplicate warehouse creation ### 3. Backend proxy logging Files: - `src/lib/backend-fetch-logger.ts` - `src/instrumentation.ts` - `.env.local` uses `DEBUG_BACKEND_PROXY=true` locally Behavior: - Logs server-side `fetch` requests to backend - Logs request method, URL, headers, body preview - Logs response status, duration, headers, body preview - Redacts authorization header Use this when tracing frontend-to-backend failures in local dev. ## 4. Product measurement mode on add product Files: - `src/app/(dashboard)/products/new/pricing/page.tsx` - `src/lib/use-product-submit.ts` - `src/app/(dashboard)/products/new/review/page.tsx` Behavior: - Each model has a `Product Measurement` switch - When enabled: - nested measurements are shown - model-level price, currency, weight, dimensions, promotion, packaging, and warehouse stock are disabled - at least 1 measurement row is required - Submit payload uses `model.hasMeasurements` - When measurement mode is active, model-level numeric fields are zeroed and model warehouses are omitted ## 5. Product measurement mode on edit product File: - `src/app/(dashboard)/products/[productId]/edit/page.tsx` Behavior: - Matches add-product measurement behavior - Uses explicit `hasMeasurements` state instead of guessing from array length - Disables model-level fields when measurement mode is on ## 6. Seller product review page improvements File: - `src/app/(dashboard)/products/new/review/page.tsx` Behavior: - Review now renders actual product thumbnails using backend file URLs - Previously it only showed image indicators, which was confusing - Review also reflects measurement-based pricing correctly ## 7. Product list page improvements File: - `src/app/(dashboard)/products/page.tsx` - `src/lib/product-variants.ts` Behavior: - Edit stock/price modal supports: - choosing model - choosing measurement if present - choosing warehouse - Warehouse labels use warehouse names from master warehouse API, not raw UUIDs - Product row status badges now show explicit state like active, draft, review, unpublished, deleted, rejected - Seller `In Review` listing now uses host endpoint `/api/v1.0/seller/product/review` - If list API returns `minPrice = 0` and `maxPrice = 0`, frontend hydrates that row by fetching product detail and calculating effective price from model/measurement data Important: - This fallback exists because some list rows from backend do not include valid min/max price for measurement-based products - Example verified case: product `Pembersih Mobil` returned `0/0` in list but `IDR 50.000` in detail measurement ## 8. Product detail page improvements File: - `src/app/(dashboard)/products/[productId]/detail/page.tsx` - `src/components/product-variant-showcase.tsx` - `src/lib/product-variants.ts` Behavior: - Main category now resolves even when backend omits `subCategory.category.name` - Warehouse display now uses warehouse master names instead of UUID slices - TypeScript nullability issue for category resolution was fixed here - Seller detail, admin detail, and admin review now share the same variant presentation logic - Effective price rules: - no measurement: use model price - with measurement: use measurement price - multiple measurements: show min-max from measurements - multiple models: show min-max from effective model prices - Variant showcase now supports: - product-level summary price/weight/dimension - model selector - measurement selector - selected variant detail - model image thumbnail switching ## 9. Admin review page improvements File: - `src/app/admin/review/[productId]/page.tsx` Behavior: - Review supports model + measurement structures - New product review and compare review now handle measurement-driven price/weight/dimension/promo/stock - Compare view highlights updated sections using backend compare response and `isUpdate` - Product images are rendered using main image + gallery images - TypeScript issue around `row.field` nullability was fixed here - Single-product review view now follows admin product detail layout more closely - Compare view stays separate only for product update review - Approve/reject action flow: - UI `POST /api/admin/review/{productId}` - new create accept -> host `POST /api/v1.0/product/accept/{productId}` with `{ "state": "PUBLISHED" }` - update accept -> host `PUT /api/v1.0/product/accept/{productId}` with `{ "state": "PUBLISHED" }` - create reject -> host `POST /api/v1.0/product/reject/{productId}` - update reject -> host `PUT /api/v1.0/product/reject/{productId}` - Review approve does not resubmit full product payload. It only submits action and state. ## 10. Dashboard shell and search Files: - `src/app/(dashboard)/layout.tsx` - `src/app/(dashboard)/dashboard/page.tsx` Behavior: - Bell and message icons are intentionally grayed/disabled because no backend function exists yet - Dashboard search now resolves query results across dashboard content instead of behaving like a dead input ## 11. Sidebar submenu reliability Files: - `src/components/product-submenu-nav.tsx` - `src/components/admin-product-submenu-nav.tsx` Behavior: - Click behavior was hardened because submenu items were sometimes not navigating - Navigation is explicit via `router.push(...)` ## Translation Files Touched - `src/lib/translations/id.ts` - `src/lib/translations/en.ts` These include labels added for statuses and stock/price modal UI. ## Important Findings ### Product image inconsistency on `Pembersih Mobil` Verified seller account: - `Pendopo@Pendopo.com` - password: `password` Product: - `Pembersih Mobil` - ID: `92a8fae0-d067-4c90-be24-da31012aeaf9` Verified backend behavior: - list endpoint row returned `minPrice: 0`, `maxPrice: 0` - detail endpoint returned one measurement priced at `IDR 50.000` - detail endpoint currently returns: - `imageId: null` - `productImages: []` - `model.imageId: null` Implication: - product images are currently absent in backend detail payload for this product - if user reports image visible in older browser tab, suspect stale tab state before assuming frontend regression ### Admin review image issue For at least one reviewed product, backend review payload returned: - `image: null` - `imageId: null` - `productImages: []` In that case frontend cannot render images. If an image is missing in review, verify backend review payload before debugging frontend. ### Edit product empty main image behavior In edit product submit flow, empty `imageId` is currently sent as `undefined`, which means the field is omitted from JSON payload, not sent as `null` and not sent as empty string. If backend requires explicit image removal via `null`, this behavior will need to be changed. ### Seller in-review API note Postman latest collection contains: - seller review listing: `/api/v1.0/seller/product/review` - generic review detail: `/api/v1.0/product/review/{productId}` Current app matches this for listing and still uses generic review detail endpoint for product review detail. ## Local Dev Notes Run local dev: ```bash npm run dev ``` Build verification: ```bash npm run build ``` ## Dev Server Update Guide Based on current deployment notes, dev server update flow is: ```bash sudo -iu inadev cd ~/apps/ina-trading-web git fetch origin git checkout main git pull origin main npm ci npm run build pm2 restart ina-trading-dev pm2 save sudo -iu inadev pm2 status ``` Current expected deployed commit after latest push: ```bash 7e6446b ``` Verify on server: ```bash git rev-parse HEAD ``` Optional logs: ```bash sudo -iu inadev pm2 logs ina-trading-dev --lines 100 ``` ## Suggested Next Checks - Verify whether backend expects `null` when main image is intentionally removed during edit - Verify seller and admin review payload consistency for image fields - Verify warehouse master API always contains all warehouse IDs referenced in product payloads - Verify whether seller in-review detail also has a seller-specific detail endpoint in backend/Postman, to align with seller-specific listing endpoint - Investigate when product images were lost for `Pembersih Mobil` and whether edit/update flow can preserve old image ids more defensively - If submenu click issue still appears, inspect layout overlays with browser tooling - Consider adding field-level compare highlighting, not only section-level highlighting, in admin review compare page ## Files Most Likely To Be Relevant Next - `src/app/(dashboard)/products/new/pricing/page.tsx` - `src/app/(dashboard)/products/[productId]/edit/page.tsx` - `src/app/(dashboard)/products/new/review/page.tsx` - `src/app/(dashboard)/products/[productId]/detail/page.tsx` - `src/app/(dashboard)/products/page.tsx` - `src/app/admin/review/[productId]/page.tsx` - `src/components/product-variant-showcase.tsx` - `src/lib/product-variants.ts` - `src/lib/use-product-submit.ts` - `src/lib/backend-fetch-logger.ts`