이름: solution/front → solution/frontend

`backend` 옆에 `front` 가 있을 이유가 없었다. negosium 의 negodata/front 를 그대로
베꼈고 그게 왜 front 인지는 따져보지 않았다 — 근거 없이 들여온 이름이라 바로잡는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019uYhHQdssRubirPirrdJJC
This commit is contained in:
Mina Choi 2026-08-31 15:27:16 +09:00
parent 06f6438d9b
commit c85c577349
480 changed files with 22 additions and 22 deletions

View File

@ -98,7 +98,7 @@ Vite 앱은 구조상 **자기 디렉토리의 `.env` 만** 읽는다 — 그래
| 파일 | 담는 것 |
|---|---|
| `.env` | DB · JWT · 외부 API 키 · `SITE_PUBLIC_HOST` · `INDEXNOW_KEY` |
| `solution/front/.env` · `admin/.env` | 그 앱에만 있는 `VITE_*` |
| `solution/frontend/.env` · `admin/.env` | 그 앱에만 있는 `VITE_*` |
★ **두 곳에 같은 값을 적지 않는다.** 발행 호스트는 compose 가 루트의 `SITE_PUBLIC_HOST` 를
`VITE_PUBLISH_HOST` 로 흘려보낸다. 각자 적으면 canonical 과 화면 주소가 조용히 갈라진다.

View File

@ -9,7 +9,7 @@ import {toAuthUser, useAuthStore} from '@/stores/auth';
* 저장된 액세스 토큰으로 세션을 복구한다.
*
* ★ 사장님 앱과 결정적으로 다른 점: **여기서는 실패가 곧 차단이다.**
* 빌더는 로그인 없이도 돌아야 해서 인증 실패를 삼키지만(solution/front/app/provider.tsx),
* 빌더는 로그인 없이도 돌아야 해서 인증 실패를 삼키지만(solution/frontend/app/provider.tsx),
* 내부 운영 화면은 전부 RequireAuth 뒤에 있다. 두 정책을 한 앱에 두면 실수가 늘
* 느슨한 쪽으로 나기 때문에 앱을 갈랐다.
*/

View File

@ -1,5 +1,5 @@
/**
* 사장님 앱(`solution/front`)의 오리진.
* 사장님 앱(`solution/frontend`)의 오리진.
*
* ★ 앱을 가른 뒤로 빌더는 **다른 오리진**이다(로컬 :3000 / 내부 :3002).
* react-router `<Link to="/builder">` 로 두면 admin 안에서 라우트를 찾다 404 로 떨어진다.

View File

@ -4,7 +4,7 @@
"types": ["vite/client", "node"],
"paths": {
"@admin/*": ["./src/*"],
"@/*": ["../solution/front/src/*"],
"@/*": ["../solution/frontend/src/*"],
"@o2o/shared": ["../solution/shared/src/index.ts"],
"@o2o/shared/*": ["../solution/shared/src/*"]
}

View File

@ -4,7 +4,7 @@ import path from 'path';
import {defineConfig} from 'vite';
/**
* 내부 운영 화면(우리 회사용). 사장님 앱(`solution/front`)과 **번들이 갈린다** —
* 내부 운영 화면(우리 회사용). 사장님 앱(`solution/frontend`)과 **번들이 갈린다** —
* 이 앱의 라우트 이름과 코드는 사장님 브라우저에 내려가지 않는다. 그게 앱을 가른 이유다.
*
* ★ `@` 를 이 앱이 아니라 **사장님 앱의 src** 로 겨눈다.
@ -22,7 +22,7 @@ export default defineConfig({
resolve: {
alias: {
'@admin': path.resolve(__dirname, 'src'),
'@': path.resolve(__dirname, '../solution/front/src'),
'@': path.resolve(__dirname, '../solution/frontend/src'),
// css 는 더 구체적인 별칭이 먼저 와야 한다 — '@o2o/shared' 접두어가 먼저 걸리면
// 없는 경로(shared/src/tokens.css)로 떨어진다.
'@o2o/shared/tokens.css': path.resolve(__dirname, '../solution/shared/src/styles/tokens.css'),

View File

@ -111,7 +111,7 @@ services:
# rollup·esbuild 네이티브 바이너리를 리눅스 컨테이너가 못 쓴다.
- /app/node_modules
- /app/solution/site/node_modules
- /app/solution/front/node_modules
- /app/solution/frontend/node_modules
- /app/admin/node_modules
# ★ 산출물은 named volume. 호스트 경로면 재배포로 코드를 갈아엎는 순간 전 사이트가 404 다.
- site-out:/app/solution/site/out
@ -144,7 +144,7 @@ services:
- ./admin:/app/admin
- /app/node_modules
- /app/solution/site/node_modules
- /app/solution/front/node_modules
- /app/solution/frontend/node_modules
- /app/admin/node_modules
ports:
# ★ 운영에서는 내부망에만 연다. 0.0.0.0 으로 열면 앱을 가른 의미가 없다.

View File

@ -1,7 +1,7 @@
# API 사용 이력 · 비용 기록
**집계 시각: 2026-08-27 08:59 KST**
집계 대상: o2o-web4ai 프로젝트 전체 (backend · solution/front · solution/site)
집계 대상: o2o-web4ai 프로젝트 전체 (backend · solution/frontend · solution/site)
---
@ -103,7 +103,7 @@
|---|---|---|---|---|---|---|
| `4db7aca5` | 메인 (backend 주력) | 08-26 16:23 ~ 08-27 08:55 | 157 | 266,385 | 35,748,750 | **$32.65** |
| `99be2a6c` | 메인 | 08-26 17:24 ~ 08-27 08:58 | 92 | 124,641 | 16,660,246 | **$19.79** |
| `19be092e` | 메인 (solution/front) | 08-27 08:42 ~ 08:58 | 29 | 25,903 | 2,476,298 | $3.37 |
| `19be092e` | 메인 (solution/frontend) | 08-27 08:42 ~ 08:58 | 29 | 25,903 | 2,476,298 | $3.37 |
| `agent-a58…` | 서브에이전트 | 08-27 08:51 ~ 08:57 | 13 | 6,173 | 5,741,359 | $3.21 |
| `agent-afa…` | 서브에이전트 | 08-27 08:52 ~ 08:55 | 14 | 423 | 6,132,381 | $3.21 |
| `6052d29a` | 메인 (이 기록 작성 세션) | 08-27 08:52 ~ 08:58 | 21 | 23,936 | 1,678,581 | $2.92 |

View File

@ -133,7 +133,7 @@ negosium 대응: `negodata/{backend, front}` 가 프로젝트 안에서 f/b 를
### 두 앱이 코드를 나눠 갖는 방식 — `@` 가 solution 을 가리킨다
`admin/vite.config.ts` 와 `tsconfig.json` 에서 **`@` 는 `solution/front/src`** 다.
`admin/vite.config.ts` 와 `tsconfig.json` 에서 **`@` 는 `solution/frontend/src`** 다.
admin 자기 파일만 `@admin` 이다.
왜 복제하지 않았나: 내부 화면이 쓰는 API 클라이언트·UI 프리미티브·수집 배선이 solution 에
@ -154,7 +154,7 @@ admin 자기 파일만 `@admin` 이다.
남은 일은 **라우터 표면을 청중별로 가르는 것**뿐이다:
```
/api/v1/... 사장님 (solution/front) — 자기 리소스만
/api/v1/... 사장님 (solution/frontend) — 자기 리소스만
/api/v1/admin/... 내부 (admin) — 라우터 레벨에서 role >= DEVELOPER 강제
```
@ -177,7 +177,7 @@ admin 자기 파일만 `@admin` 이다.
- `/api/v1/admin/*` 라우터 분리 + role 의존성 (위)
- 사장님 **"내 사이트 관리"** 화면. 이게 붙으면 빌더도 로그인 뒤로 들어간다 —
그때 `solution/front` 의 인증 정책을 다시 본다.
그때 `solution/frontend` 의 인증 정책을 다시 본다.
- 운영 배포에서 `admin`(:3002)을 내부망에만 여는 것. compose 는 `ADMIN_BIND` 기본값을
`127.0.0.1` 로 두었다. **0.0.0.0 으로 열면 앱을 가른 의미가 없다.**

View File

@ -60,8 +60,8 @@ Perplexity 응답의 영업시간, 가격 같은 본문 정보는 사용하지
- `backend/services/external/perplexity.py`
- `backend/services/prompts/channel_discovery.py`
- `solution/front/src/features/onboarding/useCollectFlow.ts`
- `solution/front/src/features/onboarding/ChannelConfirmPanel.tsx`
- `solution/frontend/src/features/onboarding/useCollectFlow.ts`
- `solution/frontend/src/features/onboarding/ChannelConfirmPanel.tsx`
## 4. 크롤링
@ -248,7 +248,7 @@ AEO 항목:
- `backend/services/seo_audit.py`
- `backend/router/v1/site/site.py`
- `solution/front/src/pages/SeoAuditPage.tsx`
- `solution/frontend/src/pages/SeoAuditPage.tsx`
API:

6
package-lock.json generated
View File

@ -9,7 +9,7 @@
"version": "0.0.0",
"workspaces": [
"solution/shared",
"solution/front",
"solution/frontend",
"solution/site",
"admin"
],
@ -1454,7 +1454,7 @@
"link": true
},
"node_modules/@o2o/front": {
"resolved": "solution/front",
"resolved": "solution/frontend",
"link": true
},
"node_modules/@o2o/shared": {
@ -8787,7 +8787,7 @@
"vitest": "^4.1.11"
}
},
"solution/front": {
"solution/frontend": {
"name": "@o2o/front",
"version": "0.0.0",
"dependencies": {

View File

@ -5,7 +5,7 @@
"type": "module",
"workspaces": [
"solution/shared",
"solution/front",
"solution/frontend",
"solution/site",
"admin"
],
@ -21,7 +21,7 @@
"prerender": "npm run prerender -w @o2o/site",
"lint": "npm run lint -w @o2o/front && npm run lint -w @o2o/admin && npm run lint -w @o2o/site",
"orval": "npm run orval -w @o2o/front",
"clean": "rm -rf solution/front/dist admin/dist solution/site/dist solution/site/.ssr-dist node_modules/.vite"
"clean": "rm -rf solution/frontend/dist admin/dist solution/site/dist solution/site/.ssr-dist node_modules/.vite"
},
"engines": {
"node": ">=20"

View File

@ -7,7 +7,7 @@
## 현재 상태
**수집 → 생성 → 빌드 → 발행 파이프라인이 API 로 다 열렸다.** 프론트(`solution/front`)가 이 API 를 붙여 쓴다.
**수집 → 생성 → 빌드 → 발행 파이프라인이 API 로 다 열렸다.** 프론트(`solution/frontend`)가 이 API 를 붙여 쓴다.
| 모듈 | 상태 | 역할 |
|---|---|---|

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 788 KiB

After

Width:  |  Height:  |  Size: 788 KiB

View File

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 202 KiB

View File

Before

Width:  |  Height:  |  Size: 367 B

After

Width:  |  Height:  |  Size: 367 B

View File

Before

Width:  |  Height:  |  Size: 236 B

After

Width:  |  Height:  |  Size: 236 B

View File

Before

Width:  |  Height:  |  Size: 210 B

After

Width:  |  Height:  |  Size: 210 B

View File

Before

Width:  |  Height:  |  Size: 430 B

After

Width:  |  Height:  |  Size: 430 B

View File

Before

Width:  |  Height:  |  Size: 433 B

After

Width:  |  Height:  |  Size: 433 B

View File

Before

Width:  |  Height:  |  Size: 287 B

After

Width:  |  Height:  |  Size: 287 B

View File

Before

Width:  |  Height:  |  Size: 235 B

After

Width:  |  Height:  |  Size: 235 B

View File

Before

Width:  |  Height:  |  Size: 384 B

After

Width:  |  Height:  |  Size: 384 B

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 287 B

After

Width:  |  Height:  |  Size: 287 B

Some files were not shown because too many files have changed in this diff Show More