qcast-front/CLAUDE.md
sangwook yoo 3ac66feba2 chore: .agents/.claude 설정·CLAUDE.md·AGENTS.md git 추적 추가
gitignore 의 *.md / .claude/ 차단을 풀어 다음 파일을 git 으로 추적.
- /CLAUDE.md, /AGENTS.md (루트 에이전트 가이드)
- .agents/**/*.md (skills 문서 95개)
- .claude/settings.json (Claude Code 프로젝트 설정)
.claude/worktrees/ 는 git worktree 메타이므로 신규 ignore 라인으로 제외.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 18:05:03 +09:00

111 lines
9.2 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
> The repository README.md is unusually thorough. Treat it as authoritative for stack, directory layout, env vars, routes, and troubleshooting — this file only highlights what's non-obvious or easy to get wrong.
## Project at a glance
Q.CAST Front — a Next.js 14 (App Router) frontend for solar-panel layout planning, quoting, and management, targeted at the Japanese (Q.CELLS) market with `ja`/`ko` i18n. JavaScript + TypeScript (`allowJs`, `strict: false`). Path alias `@/* → ./src/*`.
## Common commands
All scripts use `env-cmd` to inject the right `.env.<mode>` file. There is **no test runner** wired into `package.json`.
```bash
yarn dev # local dev (.env.localhost)
yarn dev:local-api # local dev pinned to http://localhost:8080 API
yarn local:dev # .env.local.dev mode
yarn build # production build (.env.production)
yarn build:dev # development build (.env.development)
yarn start:cluster1 # next start -p 5000 (.env.production) — used by PM2
yarn start:dev # next start -p 5010 (.env.development)
yarn serve # custom HTTP:3000 + HTTPS:3001 (needs ./certificates/*.pem)
yarn lint # next lint
```
PM2 entrypoints (`ecosystem.config.js`, `prd1/prd2/dev/dev.local.ecosystem.config.js`) wrap `startscript*.js`, which `child_process.exec` the yarn scripts above.
## Architecture — the parts that span many files
### Mode routing through `src/config/`
Runtime config is selected at module load by `src/config/config.export.js`, which switches on `process.env.NEXT_PUBLIC_RUN_MODE` between `config.local.js`, `config.local.dev.js`, `config.development.js`, `config.production.js`. Never read env values directly in feature code — import from here so mode switches stay in one place.
### Session / auth gate
`iron-session` cookies are the session source of truth (`src/lib/session.js`, `src/lib/authActions.js`). `src/app/layout.js` checks the session at the root and redirects every non-login route to `/login` when missing. `SESSION_SECRET` must be set (≥32 bytes). The session also carries `storeLvl` (1차/2차 판매점) which drives quote-render branches, builder number, and group ID. Q-Order / Q-Musubi support **autoLogin** flows via `NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL` / `NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL`.
`src/middleware.js` injects `x-pathname` into request headers so the root layout can branch on the active route.
### Floor Plan canvas (the heart of the app)
`src/app/floor-plan/**` is built on **Fabric.js 5.5.2**. The model has three layered concerns:
1. **Roof covering** (`hooks/roofcover`, `components/floor-plan/modal/roofShape` / `outerlinesetting` / `eavesGable` …): outer wall lines, auto/manual roof-shape detection, guides, eaves & kerabs, flow up/down, outer-line edit & offset, roof-face assignment.
2. **Placement surface** (`hooks/surface`, `components/floor-plan/modal/placementShape` …): slope, placement/shape drawing, object placement, bulk delete.
3. **Module / circuit** (`hooks/module`, `components/floor-plan/modal/panelBatch` …): basic settings, circuit & rack config, orientation.
A modal under `components/floor-plan/modal/<feature>` pairs with a hook under `hooks/<roofcover|surface|module|object|option|...>`. Keep that pairing when adding new tools.
**Fabric extensions** live in `src/components/fabric/QLine.js`, `QPolygon.js` and `src/util/fabric-extensions.js`. Prototype patches must be defined in one place and loaded together — patching elsewhere causes hard-to-debug shape issues.
**Context menus** are unified through `useContextMenu` + the `contextMenu` Recoil atom. The per-target menu inventory is documented in `docs/Canvas Status.md` — match that list when changing menu wiring.
**Plan persistence** (serialize/restore) is in `src/lib/canvas.js` and `src/util/canvas-util.js`. Recent commits (`a5e794b3`, `2aef32e0`) added a three-layer guard (entry / cache / save) and `SizeSetting` input guards against 0-area apertures/shadows/dormers — when touching plan load/save or size inputs, do not weaken or remove these guards without understanding the failure mode (`InvalidStateError` from corrupted plans).
### State — Recoil, split by domain
Atoms live under `src/store/` and are split by domain (`canvasAtom`, `roofAtom`, `estimateAtom`, `modalAtom`, `menuAtom`, `settingAtom`, …). When adding state, find the existing domain atom rather than introducing a new global. `RecoilWrapper.js` mounts the root; `QcastProvider.js` composes the rest of the global providers (session, global data, global loading) for the App Router root layout.
### Build / runtime quirks
- `next.config.mjs` sets `resolve.fallback = { fs: false }` and externalizes `canvas`, `utf-8-validate`, `bufferutil` as commonjs. Adding a node-only dep usually means adding it to that externals list.
- `experimental.staleTimes` are all **0** on purpose — App Router cache is disabled so plan/estimate pages always refetch. Don't re-enable without checking the plan-stale failure mode.
- `reactStrictMode: false`. Don't assume double-render semantics.
- HTTPS local dev via `yarn serve` needs `./certificates/key.pem` and `cert.pem` (gitignored).
## Conventions that are easy to violate
- **Prettier**: single quote, **no semicolons**, tabWidth 2, printWidth 150, trailingComma all (`.prettierrc`). Run `yarn lint` before declaring done.
- **No raw `alert()`** — always go through `useSwal` / `useMessage` + `sweetalert2`. See `docs/메세지 처리 가이드.pdf`.
- **Path alias** — prefer `@/...` over relative `../../..` chains.
- **Logging** — never `console.log` directly in shipped code. Use `src/util/logger.js`, which no-ops unless `NEXT_PUBLIC_ENABLE_LOGGING=true`. `src/util/debugCapture.js` POSTs to `/api/debug` for server-side capture (also gated by the same flag).
- **Commit messages** follow `.gitmessage.txt`:
```
[일감번호] : [제목]
[작업내용] :
```
Recent commits use a slightly tighter `[2204] <subject><detail>` form; mirror neighboring commits on the branch.
- **`.env.*`** can contain real secrets — never paste contents into PR bodies, issues, or chat. `.env.*.local` is gitignored for machine-local overrides.
## Reference docs in `docs/`
- `Canvas Status.md` — canvas feature status and right-click menu inventory per target type.
- `Qcast coding convention.pdf`, `Qcast development guilde.pdf` — full conventions / dev guide.
- `메세지 처리 가이드.pdf` — modal & alert message rules.
- `git commit message Convention.pdf` — commit format.
- `Nextjs 14 컴포넌트에 대해서….pdf` — App Router server/client component notes.
- `dictionary.txt` — domain vocabulary (roof / panel terms in JP/KR).
## Always Do
- All answers and reasoning processes must be written in Korean.
- Once the task is complete, use a sub-agent to perform lint checks, type checks, and build checks.
- When performing a lint check, ensure that any errors are resolved before proceeding, and make an effort to resolve any warnings that arise.
- When committing, write the prefix in English, while the rest of the title and content in Korean.
- Upon task completion, update the CLAUDE.md and README.md documents if necessary.
- When working, commit in meaningful units that can be explained in a single sentence.
## graphify
A persistent knowledge graph of `src/` lives at `graphify-out/` (built by `/graphify src`). Prefer it over grep for architectural questions.
**When to consult it**
- Before answering "how does X relate to Y", "what depends on Z", or any cross-module question, read `graphify-out/GRAPH_REPORT.md` (god nodes, surprising connections) and use `graphify query "..."` / `graphify path "A" "B"` / `graphify explain "..."` — these traverse EXTRACTED + INFERRED edges instead of scanning files.
- If `graphify-out/wiki/index.md` exists, prefer it over raw file reads.
- The PreToolUse hook in `.claude/settings.json` will remind you when you reach for `grep` / `rg` / `find`.
**Keeping it fresh — auto-update is wired up**
1. **In-session (you, Claude)**: after any batch of `Edit` / `Write` on files under `src/`, run `graphify update .` to incrementally re-extract changed files. AST-only, no LLM cost, takes a few seconds. Do this *before* answering follow-up architectural questions on the changed code, otherwise the graph is stale.
2. **At commit (automatic)**: a `post-commit` git hook (installed via `graphify hook install`, lives in the main repo's `.git/hooks/`, shared across worktrees) re-runs AST extraction on changed code files after every commit. Combined with the "commit in meaningful units" rule above, the graph stays current with minimal effort.
3. **Doc / image changes**: the post-commit hook ignores non-code files. Run `graphify update .` manually after touching docs that affect the graph (rare — this project's graph is code-only).
**Don't**
- Don't rebuild the whole graph (`/graphify src` from scratch) unless `graph.json` is missing or corrupt — `graphify update .` is strictly faster and preserves cached analysis.
- Don't trust `INFERRED` edges blindly — the AST extractor marks JS import-derived `calls` edges as INFERRED. Verify with the actual source when the answer hinges on call semantics (see useMessage trace example).