Guidance for Codex and other coding agents working in this repository.
This is a Customer's Canvas Hub sample application built with:
- Node.js 20.17+.
- Express 4 backend written in TypeScript.
- React 18 frontend written in TypeScript.
- Vite 5 for frontend build/dev integration.
vite-expressto serve the React app from the Express server.- SCSS, Bootstrap, and React Bootstrap for UI styling.
The app demonstrates Customer's Canvas editors integrations through Workflow Elements and UI Framework JS libraries. Additionally, you will find some examples of using Customer's Canvas Hub API for storefront authentication, editor embedding, design/template operations, and project saving.
src/server/contains the Express backend, Customer's Canvas API wrappers, auth, configuration, middleware, and server entrypoint.src/client/contains the React app, dynamic code example routes, shared frontend API helpers, constants, interfaces, assets, and styles.src/client/code-examples/contains code example editor integrations. Prefer adding new code example experiences here.src/client/components/contains reusable React UI components.src/client/shared/contains frontend helpers and API service wrappers.src/client/interfaces/contains shared frontend TypeScript interfaces.public/contains static Vite assets.code-examples.jsonc.sampleis the tracked template for local code example configuration.code-examples.jsoncis local, ignored configuration for enabled examples and their params.dist/is generated output. Do not edit it manually.node_modules/is installed dependencies. Do not edit it.
npm installinstalls dependencies.npm run devstarts the development workflow: watches the server TypeScript build and runs the compiled Express server.npm run buildbuilds the server and frontend.npm run build:servercompiles only the backend TypeScript.npm startruns the production server fromdist/server/main.js.
There is no dedicated test script in package.json at the time of writing. For verification, run npm run build unless the requested change has a narrower safe check.
.envcontains local credentials and must not be committed or exposed in answers.- Use
.env.sampleas the source of truth for expected configuration keys. code-examples.jsonccontains local example IDs and params and must not be committed or exposed in answers if it contains private identifiers.- Use
code-examples.jsonc.sampleas the source of truth for expected code example configuration shape. - Backend-only secrets must not be moved into frontend code.
- Only variables prefixed with
VITE_are available to the frontend throughimport.meta.env. - Customer's Canvas credentials such as
CCHUB_CLIENTIDandCCHUB_CLIENTSECRETbelong on the server side only. - Do not log tokens, client secrets, or full credential-bearing configuration objects.
- Keep changes small and focused; do not refactor unrelated code.
- Do not introduce new architectural patterns or dependencies without explicit approval.
- Respect layer boundaries and dependency direction.
- If unclear, prefer consistency with existing code and ask for clarification.
- The project uses ESM (
"type": "module") andmoduleResolution: "NodeNext". - Server-side relative TypeScript imports should use
.jsextensions so compiled Node ESM works correctly. - Keep
strictTypeScript compatibility. - Prefer existing interfaces in
src/client/interfaces/before adding new shape definitions. - Avoid
anyunless it is already part of an Express error boundary or third-party API escape hatch.
- Express entrypoint:
src/server/main.ts. - Keep route handlers thin and small. Move all logic, file reading/writing, and API client usage to separate service classes/functions in separate file under
src/server/. - Wrap async route handlers with
asyncHandler. - Add
logEndpoint(logger)to new API routes unless there is a specific reason not to. - Return JSON responses with stable shapes and update matching frontend interfaces.
- Preserve the current startup behavior where the server obtains a Customer's Canvas access token before listening.
- When adding configuration, read it through
CCHubConfigurationrather than scatteringprocess.envreads across services. - Code example configuration is read from
code-examples.jsoncthroughCodeExampleConfigurationService.
- React entrypoint:
src/client/main.tsx. - App routes are registered in
src/client/App.tsx. - Code example navigation is driven by
GET /api/code-examples. - If adding a new code example page, add the React component under
src/client/code-examples/, update the registry inApp.tsx, and updatecode-examples.jsonc.sample. - Keep server communication in
src/client/shared/server-api-service.tsor a similarly focused helper. - Use existing SCSS/component conventions before introducing a new styling pattern.
- Do not expose backend secrets or server-only Customer's Canvas API calls in browser code.
- Keep storefront/user-token acquisition on the backend.
- Treat
userId,privateDesignId,publicDesignId,mockupIds,orderId, and product/reference IDs as integration identifiers; validate or guard them where user input is accepted. - Prefer small, readable code example code over over-abstracted production frameworks. This repository is a sample app, so clarity matters.
- When changing code example behavior, keep the README.md, AGENTS.md,
.env.sample, andcode-examples.jsonc.samplealigned if new configuration is required.
- Do not manually edit
dist/,node_modules/, lockfile internals, or generated artifacts. - Do not run dependency updates unless the task explicitly requires it.
- If dependencies must change, update
package.jsonandpackage-lock.jsontogether using npm.
Before finishing a code change:
- Run
npm run buildwhen feasible. - If only backend code changed,
npm run build:serveris an acceptable narrower check. - For UI changes, start
npm run devwhen practical and verify the affected route in the browser. - Note any verification that could not be run and why.
- If any archtectural chances was made, ensure that it is reflected in AGENTS.md.
- Follow the existing formatting style in nearby files.
- Keep comments useful and sparse.
- Prefer clear names over clever abstractions.
- Keep changes scoped to the requested behavior.
- Do not rewrite unrelated files or refactor broadly unless the task asks for it.