This repository is a starter template for building apps that use the DataDoe API with Amazon seller/vendor account data.
Your goal in this repo is to:
- help build simple, stable business apps on top of DataDoe data,
- keep implementation understandable for non-technical users,
- avoid unnecessary complexity.
Before any planning or implementation, you must read README.md in the project root to understand what this starter repository is, what it includes, its tech stack, and how it works.
README.mdis the source of truth for the repository purpose, included features, tech stack, usage instructions, and DataDoe API references.- If
README.mdcontent conflicts with your assumptions,README.mdwins. - Do not skip this step — context from
README.mdinforms all subsequent decisions.
- Use simple language.
- If user request is vague (for example: "I want to see XYZ"), ask follow-up questions first.
- Confirm understanding before implementation when requirements are unclear.
- Prefer safe, predictable implementations over clever ones.
- After creating an implementation plan, explain it to the user at a high level (what will be built), without deep file/code details unless user asks.
Before implementing any feature, perform this exact flow:
- Check if
.env.localexists. - If missing, create
.env.localbased on.env.example. - Verify
DATADOE_API_KEYis present and non-empty. - Run a health check request with
curlagainst:https://api.datadoe.com/api/v1/util/sellers-and-vendors- header:
datadoe-api-key: <DATADOE_API_KEY>
- If key is missing/invalid:
- ask user in chat to provide the DataDoe API key,
- write the key into
.env.localon behalf of the user.
- Repeat key check + health check until connection succeeds.
- Do not continue to implementation planning or coding until the health check succeeds.
Note
- You should do key pasting for non-technical users (do not force manual IDE editing).
- Never print full secrets back to user.
This repository is a ready-to-use proof of concept. Out of the box, with only a DataDoe API key configured, the included dashboard app is fully operational. However, when you begin building a custom app for the user, you must flush the starter feature code first before writing any new feature code.
The flush is required when the user asks you to build something new (a custom app, new features, a different dashboard, etc.). Do not flush if the user only wants to run, inspect, or make minor tweaks to the existing starter dashboard.
src/features/dashboard/— entire directory (components, hooks, lib, types, barrel export)src/app/api/dashboard/route.ts— dashboard-specific API route- Dashboard import and rendering from
src/app/page.tsx— replace with an empty/placeholder page
src/components/ui/*— all generic shadcn components (badge, button, card, select, table, data-table)src/app/globals.css— global styles and design tokenssrc/app/layout.tsx— root layoutsrc/app/page.tsx— keep the file itself, only clear dashboard contentsrc/app/providers.tsx— React Query provider setupsrc/lib/datadoe-client.ts— DataDoe Axios client with auth and error handlingsrc/lib/utils.ts— Tailwind class merge utilitysrc/app/api/sellers/route.ts— generic seller/vendor account fetching (entry point for most DataDoe apps)src/app/api/datadoe/[...path]/route.ts— generic DataDoe API proxysrc/types/api/*— shared API types (exports, sellers)
Do not start writing new feature code until all three conditions are met:
- You have explicit requirements from the user (what to build).
- You have prepared an implementation plan accepted by the user.
- The starter feature code has been flushed per the rules above.
- Follow user requirements and approved implementation plan strictly.
- Do not add extra features not requested by the user.
- Keep scope tight and explicit.
- If new ambiguity appears during implementation, pause and ask follow-up questions.
This repository follows a feature-based folder structure. All code related to a specific product feature lives inside its own module under src/features/. Generic, reusable code lives in shared directories.
src/
├── app/ # Next.js App Router: pages, layouts, API routes
│ ├── api/ # Server-side API route handlers
│ │ └── <feature>/ # Feature-specific API routes
│ ├── <route>/ # Route segments (pages + layouts)
│ ├── globals.css # Global styles
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Home page
│ └── providers.tsx # App-wide providers
├── components/ # Generic, reusable UI components
│ └── ui/ # shadcn/design-system primitives
├── features/ # Feature modules (one folder per product feature)
│ └── <feature-name>/
│ ├── components/ # UI components specific to this feature
│ ├── hooks/ # React hooks specific to this feature
│ ├── lib/ # Helpers, mappers, utilities for this feature
│ ├── types/ # TypeScript types for this feature
│ └── index.ts # Public barrel export
├── lib/ # Shared utilities (API client, helpers)
└── types/ # Shared TypeScript types
└── api/ # API request/response types
- Feature-specific code (components, hooks, helpers, types used only by one feature) goes into
src/features/<feature-name>/. - Reusable UI components (no business logic, usable across features) go into
src/components/ui/. - Shared utilities (API client, generic helpers) go into
src/lib/. - Shared types (API DTOs, cross-feature types) go into
src/types/. - API route handlers go into
src/app/api/<feature>/for feature-specific routes, orsrc/app/api/root level for generic routes. - Each feature module must have a barrel
index.tsthat exports its public API. - Never import internal feature files from outside the feature — always import through the barrel
index.ts.
After finishing a feature:
- run lint checks,
- run build/type checks,
- fix detected issues before finishing.
When implementation is complete and the app is working, ask the user if they want to share temporary public access to their local app through ngrok.
If user confirms, provide this manual:
-
Install ngrok on macOS (Terminal):
brew install ngrok
-
For other operating systems, use the official guide:
-
Configure ngrok auth token:
ngrok config add-authtoken "<YOUR_AUTHTOKEN>" -
Start a public endpoint:
ngrok http 3000
Never expose user secrets in chat (API keys, ngrok auth token values, etc.).
- Always follow style/design constraints from
DESIGN.md. - Do not introduce styles outside those design rules unless user explicitly requests it.
- Implement user-friendly errors for non-technical users.
- Surface clear next steps (what to do next) when possible.
- If bug is reported, reproduce, isolate cause, fix, and verify.
For every API-related implementation, debugging task, or schema/data mapping change:
- always reference DataDoe API documentation first:
https://api.datadoe.com/api/v1/docs - always reference DataDoe data scheme JSON:
https://api.datadoe.com/api/v1/spec/data-scheme - validate endpoint requirements, field names, and payload shape against these sources before coding
- if code and docs conflict, treat the DataDoe docs/scheme as source of truth and adjust implementation
Always apply strong software engineering practices, especially for API-driven features.
- Use typed request/response models.
- Validate payloads and response assumptions.
- Keep API calls centralized (shared client/helpers), avoid duplicated request logic.
- Keep secrets server-side only.
- Respect API limits and constraints (rate limits, retries, backoff, timeouts).
- Design async operations to be safe and predictable.
- Avoid uncontrolled parallelism that can break rate limits.
- Use explicit polling intervals, stop conditions, and timeout guards.
- Handle partial/in-progress states clearly.
- Ensure polling loops can terminate and report useful errors.
- Parse and map API responses defensively.
- Handle missing/nullable fields safely.
- Provide actionable, user-friendly messages for non-technical users.
- Preserve technical trace context when available (for example request IDs).
- Differentiate validation, auth, rate-limit, not-found, and server errors.
- Use best-practice frontend architecture and state patterns.
- Prefer predictable data-fetching patterns (query keys, caching strategy, enabled conditions).
- Keep UI components focused and reusable.
- Prevent duplicate requests and invalid user actions with clear disabled/loading states.
- Keep UX clear during loading, empty, error, and success states.