agentic-dev 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/.claude/CLAUDE.md +1 -1
  2. package/.env.example +2 -2
  3. package/README.md +5 -5
  4. package/client/{platform → web}/Dockerfile +3 -3
  5. package/client/web/Dockerfile.dev +18 -0
  6. package/client/{platform → web}/README.md +3 -3
  7. package/client/{platform → web}/index.html +1 -1
  8. package/client/{platform → web}/package.json +7 -7
  9. package/client/{platform/scripts/ui-parity-platform-adapter.mjs → web/scripts/ui-parity-web-adapter.mjs} +7 -7
  10. package/client/{platform → web}/src/auth/AuthProvider.tsx +1 -1
  11. package/compose.yml +6 -6
  12. package/infra/compose/.env.dev.example +3 -3
  13. package/infra/compose/.env.prod.example +3 -3
  14. package/infra/compose/README.md +1 -1
  15. package/infra/compose/dev.yml +5 -5
  16. package/infra/compose/prod.yml +6 -6
  17. package/infra/terraform/openstack/dev/terraform.tfvars.example +3 -3
  18. package/infra/terraform/openstack/prod/terraform.tfvars.example +3 -3
  19. package/lib/scaffold.mjs +7 -7
  20. package/package.json +2 -2
  21. package/scripts/dev/audit_sdd_build_ast.py +9 -9
  22. package/sdd/01_planning/01_feature/auth_feature_spec.md +2 -2
  23. package/sdd/01_planning/01_feature/catalog_feature_spec.md +3 -3
  24. package/sdd/01_planning/01_feature/order_feature_spec.md +11 -11
  25. package/sdd/01_planning/02_screen/INDEX.md +2 -2
  26. package/sdd/01_planning/02_screen/README.md +2 -2
  27. package/sdd/01_planning/03_architecture/templates_system_architecture.md +3 -3
  28. package/sdd/01_planning/05_api/templates_api_contract.md +3 -3
  29. package/sdd/01_planning/06_iac/templates_runtime_and_cicd_baseline.md +1 -1
  30. package/sdd/01_planning/07_integration/templates_frontend_api_integration.md +3 -3
  31. package/sdd/01_planning/10_test/templates_test_strategy.md +2 -2
  32. package/sdd/01_planning/INDEX.md +1 -1
  33. package/sdd/02_plan/02_screen/INDEX.md +1 -1
  34. package/sdd/02_plan/02_screen/README.md +1 -1
  35. package/sdd/02_plan/03_architecture/build_ast_runtime_tree_governance.md +1 -1
  36. package/sdd/02_plan/03_architecture/repository_governance.md +1 -1
  37. package/sdd/02_plan/07_integration/frontend_live_integration.md +3 -3
  38. package/sdd/02_plan/10_test/templates/{ui_parity_platform_contract.template.yaml → ui_parity_web_contract.template.yaml} +1 -1
  39. package/sdd/03_build/01_feature/domain/account_and_access.md +1 -1
  40. package/sdd/03_build/01_feature/domain/catalog_and_inventory.md +1 -1
  41. package/sdd/03_build/01_feature/domain/ordering_and_fulfillment.md +1 -1
  42. package/sdd/03_build/01_feature/service/README.md +1 -1
  43. package/sdd/03_build/01_feature/service/{platform_surface.md → web_surface.md} +3 -3
  44. package/sdd/03_build/02_screen/README.md +1 -1
  45. package/sdd/03_build/02_screen/web/README.md +5 -0
  46. package/sdd/03_build/06_iac/template_runtime_delivery.md +1 -1
  47. package/sdd/03_build/07_integration/frontend_live_integration.md +1 -1
  48. package/sdd/04_verify/01_feature/service_verification.md +2 -2
  49. package/sdd/04_verify/02_screen/web/README.md +4 -0
  50. package/sdd/04_verify/06_iac/template_runtime_delivery.md +3 -3
  51. package/sdd/99_toolchain/01_automation/agentic-dev/assets/repo-contract.template.json +11 -11
  52. package/sdd/99_toolchain/01_automation/agentic-dev/repo-contract.json +13 -13
  53. package/sdd/99_toolchain/01_automation/agentic-parity-harness-design.md +5 -5
  54. package/sdd/99_toolchain/01_automation/capture_screen_assets.mjs +4 -4
  55. package/sdd/99_toolchain/01_automation/harness-layout.md +2 -2
  56. package/sdd/99_toolchain/01_automation/parity-execution-tooling-design.md +5 -5
  57. package/sdd/99_toolchain/01_automation/screen_spec_manifest.py +17 -17
  58. package/sdd/99_toolchain/01_automation/ui-parity/README.md +10 -10
  59. package/sdd/99_toolchain/01_automation/ui-parity/interfaces/ui-parity-artifact-layout.md +1 -1
  60. package/sdd/99_toolchain/01_automation/ui-parity/interfaces/ui-parity-route-gap-interface.md +2 -2
  61. package/sdd/99_toolchain/03_templates/playwright_exactness_manifest.example.py +1 -1
  62. package/server/data/README.md +1 -1
  63. package/client/platform/Dockerfile.dev +0 -18
  64. package/sdd/03_build/02_screen/platform/README.md +0 -5
  65. package/sdd/04_verify/02_screen/platform/README.md +0 -4
  66. /package/client/{platform → web}/.dockerignore +0 -0
  67. /package/client/{platform → web}/.env.example +0 -0
  68. /package/client/{platform → web}/postcss.config.js +0 -0
  69. /package/client/{platform → web}/src/api/client.ts +0 -0
  70. /package/client/{platform → web}/src/api/orders.ts +0 -0
  71. /package/client/{platform → web}/src/app/App.tsx +0 -0
  72. /package/client/{platform → web}/src/auth/ProtectedRoute.tsx +0 -0
  73. /package/client/{platform → web}/src/auth/auth-client.ts +0 -0
  74. /package/client/{platform → web}/src/auth/types.ts +0 -0
  75. /package/client/{platform → web}/src/components/AppShell.tsx +0 -0
  76. /package/client/{platform → web}/src/components/ui/button.tsx +0 -0
  77. /package/client/{platform → web}/src/components/ui/card.tsx +0 -0
  78. /package/client/{platform → web}/src/components/ui/input.tsx +0 -0
  79. /package/client/{platform → web}/src/lib/cn.ts +0 -0
  80. /package/client/{platform → web}/src/lib/specRouteCatalog.json +0 -0
  81. /package/client/{platform → web}/src/lib/specScreens.json +0 -0
  82. /package/client/{platform → web}/src/main.tsx +0 -0
  83. /package/client/{platform → web}/src/pages/DashboardPage.tsx +0 -0
  84. /package/client/{platform → web}/src/pages/LoginPage.tsx +0 -0
  85. /package/client/{platform → web}/src/pages/OrdersPage.tsx +0 -0
  86. /package/client/{platform → web}/src/styles/globals.css +0 -0
  87. /package/client/{platform → web}/src/theme-vars.ts +0 -0
  88. /package/client/{platform → web}/src/theme.ts +0 -0
  89. /package/client/{platform → web}/src/vite-env.d.ts +0 -0
  90. /package/client/{platform → web}/tailwind.config.js +0 -0
  91. /package/client/{platform → web}/tsconfig.json +0 -0
  92. /package/client/{platform → web}/vite.config.ts +0 -0
  93. /package/sdd/01_planning/02_screen/{platform_screen_spec.pdf → web_screen_spec.pdf} +0 -0
  94. /package/sdd/99_toolchain/01_automation/assets/{platform_screen_capture → web_screen_capture}/dashboard.png +0 -0
  95. /package/sdd/99_toolchain/01_automation/assets/{platform_screen_capture → web_screen_capture}/login.png +0 -0
  96. /package/sdd/99_toolchain/01_automation/assets/{platform_screen_capture → web_screen_capture}/orders.png +0 -0
package/.claude/CLAUDE.md CHANGED
@@ -19,7 +19,7 @@ templates/
19
19
  │ └── skills/ # Claude Code repo-local skills (.claude/skills/<name>/SKILL.md)
20
20
  ├── .codex/ # Codex 설정, 에이전트, 스킬
21
21
  ├── client/
22
- │ ├── platform/ # 일반 앱 템플릿
22
+ │ ├── web/ # 일반 앱 템플릿
23
23
  │ ├── admin/ # 어드민 템플릿
24
24
  │ ├── mobile/ # 현장형 모바일 템플릿
25
25
  │ └── landing/ # 랜딩 템플릿
package/.env.example CHANGED
@@ -1,6 +1,6 @@
1
1
  SERVER_HTTP_PORT=8000
2
2
  CLIENT_LANDING_PORT=3000
3
- CLIENT_PLATFORM_PORT=3001
3
+ CLIENT_WEB_PORT=3001
4
4
  CLIENT_MOBILE_PORT=3002
5
5
  CLIENT_ADMIN_PORT=4000
6
6
 
@@ -44,7 +44,7 @@ SERVER_BOOTSTRAP_OPERATOR_NAME=Template Operator
44
44
  SERVER_CORS_ORIGINS=["http://localhost:3000","http://127.0.0.1:3000","http://localhost:3001","http://127.0.0.1:3001","http://localhost:3002","http://127.0.0.1:3002","http://localhost:4000","http://127.0.0.1:4000"]
45
45
 
46
46
  CLIENT_LANDING_VITE_API_BASE_URL=http://127.0.0.1:8000/api/v1
47
- CLIENT_PLATFORM_VITE_API_BASE_URL=http://127.0.0.1:8000/api/v1
47
+ CLIENT_WEB_VITE_API_BASE_URL=http://127.0.0.1:8000/api/v1
48
48
  CLIENT_MOBILE_VITE_API_BASE_URL=http://127.0.0.1:8000/api/v1
49
49
  CLIENT_ADMIN_VITE_API_BASE_URL=http://127.0.0.1:8000/api/v1
50
50
  CLIENT_WATCH_USE_POLLING=false
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  포함 템플릿:
6
6
 
7
7
  - [landing](./client/landing): 마케팅/브랜드 랜딩 패턴
8
- - [platform](./client/platform): 일반 제품형 플랫폼 앱 shell, dashboard/list/detail 패턴
8
+ - [web](./client/web): 일반 제품형 앱 shell, dashboard/list/detail 패턴
9
9
  - [mobile](./client/mobile): 다국어/현장 업무형 모바일 IN workspace 패턴
10
10
  - [admin](./client/admin): 운영 콘솔형 shell, sidebar/topbar/drawer/table 패턴
11
11
  - [server](./server): HTTP 기반 hexagonal/DDD 서버 패턴
@@ -17,7 +17,7 @@
17
17
  - 제품 DOM은 유지하고, 스타일 조정값은 `theme.ts` + CSS custom properties로 노출
18
18
  - proof/spec 전용 DOM 복제 대신 fixture data + parameter surface로 정렬
19
19
  - `server`는 hexagonal architecture 기준으로 `contracts + application + domain + infrastructure`를 사용
20
- - `landing`, `platform`, `mobile`, `admin`은 실제 `/api/v1/auth/login`과 `/api/v1/auth/me`를 사용하는 기준 템플릿이다.
20
+ - `landing`, `web`, `mobile`, `admin`은 실제 `/api/v1/auth/login`과 `/api/v1/auth/me`를 사용하는 기준 템플릿이다.
21
21
  - runtime baseline은 루트 `compose.yml`을 기준으로 유지하고, 여기서 4개 frontend surface, `server`, 기본 `postgres`, optional DB profile을 함께 올린다.
22
22
  - agentic baseline은 `.claude`, `.codex`, `.agent`를 함께 유지하고 downstream repo가 role agent, skill alias, Ralph harness를 그대로 가져가도록 설계한다.
23
23
  - `sdd/03_build`는 단순 구현 목록이 아니라 실제 runtime assembly를 따라 읽는 AST-style current-state 설명을 기준으로 유지한다.
@@ -42,12 +42,12 @@ SDD / delivery 원칙:
42
42
  설치형 scaffold:
43
43
 
44
44
  ```bash
45
- npx agentic-dev init my-app --template platform
45
+ npx agentic-dev init my-app --template web
46
46
  cd my-app
47
47
  cp .env.example .env
48
48
  npm install -g pnpm
49
49
  pnpm install
50
- cd client/platform
50
+ cd client/web
51
51
  npm run ui:parity:bootstrap
52
52
  ```
53
53
 
@@ -74,7 +74,7 @@ docker compose up --build
74
74
  기본 compose 포트:
75
75
 
76
76
  - `client/landing`: `3000`
77
- - `client/platform`: `3001`
77
+ - `client/web`: `3001`
78
78
  - `client/mobile`: `3002`
79
79
  - `client/admin`: `4000`
80
80
  - `server/http`: `8000`
@@ -3,13 +3,13 @@ FROM node:20-slim
3
3
  WORKDIR /app
4
4
 
5
5
  COPY pnpm-lock.yaml pnpm-workspace.yaml ./
6
- COPY client/platform/package.json ./client/platform/package.json
6
+ COPY client/web/package.json ./client/web/package.json
7
7
 
8
- RUN npm install -g pnpm@10.32.0 && pnpm install --filter @do4ai/client-platform-template...
8
+ RUN npm install -g pnpm@10.32.0 && pnpm install --filter @do4ai/client-web-template...
9
9
 
10
10
  COPY . .
11
11
 
12
- WORKDIR /app/client/platform
12
+ WORKDIR /app/client/web
13
13
 
14
14
  EXPOSE 3001
15
15
 
@@ -0,0 +1,18 @@
1
+ FROM node:20-slim
2
+
3
+ WORKDIR /app
4
+
5
+ RUN npm install -g pnpm@10.32.0
6
+
7
+ COPY pnpm-lock.yaml pnpm-workspace.yaml ./
8
+ COPY client/web/package.json ./client/web/package.json
9
+
10
+ RUN pnpm install --frozen-lockfile --filter @do4ai/client-web-template...
11
+
12
+ COPY client/web ./client/web
13
+
14
+ WORKDIR /app/client/web
15
+
16
+ EXPOSE 3001
17
+
18
+ CMD ["sh", "-lc", "pnpm exec vite --host 0.0.0.0 --port ${PORT:-3001}"]
@@ -1,4 +1,4 @@
1
- # platform
1
+ # web
2
2
 
3
3
  일반 사용자용 제품 앱 보일러플레이트다.
4
4
 
@@ -25,7 +25,7 @@ npm run dev
25
25
  npm run ui:parity:init
26
26
  ```
27
27
 
28
- 이 단계는 repo-level contract, `ui_parity_platform_contract.yaml`, route-gap manifest를 생성한다.
28
+ 이 단계는 repo-level contract, `ui_parity_web_contract.yaml`, route-gap manifest를 생성한다.
29
29
 
30
30
  첫 proof 부트스트랩:
31
31
 
@@ -44,4 +44,4 @@ npm run ui:parity:route-gap
44
44
  npm run ui:parity:proof
45
45
  ```
46
46
 
47
- 이 템플릿은 repo root의 `sdd/99_toolchain/01_automation` 도구를 사용하고, `client/platform/scripts/ui-parity-platform-adapter.mjs`는 앱별 adapter 예시다.
47
+ 이 템플릿은 repo root의 `sdd/99_toolchain/01_automation` 도구를 사용하고, `client/web/scripts/ui-parity-web-adapter.mjs`는 앱별 adapter 예시다.
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>client-platform template</title>
6
+ <title>client-web template</title>
7
7
  </head>
8
8
  <body>
9
9
  <div id="root"></div>
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "@do4ai/client-platform-template",
2
+ "name": "@do4ai/client-web-template",
3
3
  "private": true,
4
4
  "version": "0.1.0",
5
5
  "type": "module",
@@ -8,12 +8,12 @@
8
8
  "dev": "vite --host 0.0.0.0 --port 3001",
9
9
  "build": "tsc -b && vite build",
10
10
  "preview": "vite preview --host 0.0.0.0 --port 4301",
11
- "ui:parity:init": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/init_frontend_parity.sh ../.. platform",
12
- "ui:parity:bootstrap": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/bootstrap_frontend_parity.sh ../.. platform",
13
- "ui:parity:scaffold": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/run_frontend_target.sh scaffold ../.. platform",
14
- "ui:parity:materialize-references": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/run_frontend_target.sh materialize_references ../.. platform",
15
- "ui:parity:route-gap": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/run_frontend_target.sh route_gap ../.. platform",
16
- "ui:parity:proof": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/run_frontend_target.sh proof ../.. platform",
11
+ "ui:parity:init": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/init_frontend_parity.sh ../.. web",
12
+ "ui:parity:bootstrap": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/bootstrap_frontend_parity.sh ../.. web",
13
+ "ui:parity:scaffold": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/run_frontend_target.sh scaffold ../.. web",
14
+ "ui:parity:materialize-references": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/run_frontend_target.sh materialize_references ../.. web",
15
+ "ui:parity:route-gap": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/run_frontend_target.sh route_gap ../.. web",
16
+ "ui:parity:proof": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/run_frontend_target.sh proof ../.. web",
17
17
  "ui:parity": "npm run ui:parity:proof"
18
18
  },
19
19
  "dependencies": {
@@ -13,7 +13,7 @@ const routes = JSON.parse(
13
13
  const routeMap = new Map(routes.map((entry) => [entry.id, entry.route]));
14
14
 
15
15
  export default {
16
- service: "templates-platform",
16
+ service: "templates-web",
17
17
  targetBaseUrl: "http://127.0.0.1:4301",
18
18
  viewport: {
19
19
  width: 1440,
@@ -26,7 +26,7 @@ export default {
26
26
  referenceImage: `sdd/04_verify/10_test/ui_parity/reference/${screen.id}.png`,
27
27
  readySelector: "body",
28
28
  readyTimeoutMs: 10000,
29
- tags: ["template", "platform"],
29
+ tags: ["template", "web"],
30
30
  })),
31
31
  async preparePage(page, { route }) {
32
32
  await page.route("**/auth/me", async (routeRequest) => {
@@ -34,8 +34,8 @@ export default {
34
34
  status: 200,
35
35
  contentType: "application/json",
36
36
  body: JSON.stringify({
37
- id: "tmpl-platform",
38
- name: "Template Platform User",
37
+ id: "tmpl-web",
38
+ name: "Template Web User",
39
39
  email: "operator@example.com",
40
40
  role: "member",
41
41
  }),
@@ -43,17 +43,17 @@ export default {
43
43
  });
44
44
  await page.addInitScript(() => {
45
45
  window.localStorage.setItem(
46
- "platform.auth.token",
46
+ "web.auth.token",
47
47
  JSON.stringify({
48
48
  access_token: "template-access-token",
49
49
  token_type: "bearer",
50
- user_id: "tmpl-platform",
50
+ user_id: "tmpl-web",
51
51
  }),
52
52
  );
53
53
  });
54
54
  if (route === "/login") {
55
55
  await page.addInitScript(() => {
56
- window.localStorage.removeItem("platform.auth.token");
56
+ window.localStorage.removeItem("web.auth.token");
57
57
  });
58
58
  }
59
59
  },
@@ -3,7 +3,7 @@ import { createContext, useContext, useEffect, useMemo, useState, type ReactNode
3
3
  import { getMe, login as loginRequest } from "@/auth/auth-client";
4
4
  import type { AuthToken, AuthUser, LoginCommand } from "@/auth/types";
5
5
 
6
- const STORAGE_KEY = "platform.auth.token";
6
+ const STORAGE_KEY = "web.auth.token";
7
7
 
8
8
  interface AuthContextValue {
9
9
  user: AuthUser | null;
package/compose.yml CHANGED
@@ -138,19 +138,19 @@ services:
138
138
  networks:
139
139
  - template-dev
140
140
 
141
- client-platform:
141
+ client-web:
142
142
  build:
143
143
  context: .
144
- dockerfile: client/platform/Dockerfile.dev
144
+ dockerfile: client/web/Dockerfile.dev
145
145
  network: host
146
146
  environment:
147
- PORT: ${CLIENT_PLATFORM_PORT:-3001}
148
- VITE_API_BASE_URL: ${CLIENT_PLATFORM_VITE_API_BASE_URL:-http://127.0.0.1:8000/api/v1}
147
+ PORT: ${CLIENT_WEB_PORT:-3001}
148
+ VITE_API_BASE_URL: ${CLIENT_WEB_VITE_API_BASE_URL:-http://127.0.0.1:8000/api/v1}
149
149
  CHOKIDAR_USEPOLLING: ${CLIENT_WATCH_USE_POLLING:-false}
150
150
  ports:
151
- - "${CLIENT_PLATFORM_PORT:-3001}:${CLIENT_PLATFORM_PORT:-3001}"
151
+ - "${CLIENT_WEB_PORT:-3001}:${CLIENT_WEB_PORT:-3001}"
152
152
  volumes:
153
- - ./client/platform:/app/client/platform
153
+ - ./client/web:/app/client/web
154
154
  depends_on:
155
155
  server:
156
156
  condition: service_started
@@ -15,14 +15,14 @@ DEV_SERVER_MONGODB_URL=mongodb://mongo:27017
15
15
  DEV_SERVER_MONGODB_DATABASE=template
16
16
  DEV_SERVER_JWT_SECRET=change-me
17
17
  DEV_SERVER_ACCESS_TOKEN_TTL_MINUTES=120
18
- DEV_SERVER_CORS_ORIGINS=https://dev-landing.example.com,https://dev-platform.example.com,https://dev-mobile.example.com,https://dev-admin.example.com
18
+ DEV_SERVER_CORS_ORIGINS=https://dev-landing.example.com,https://dev-web.example.com,https://dev-mobile.example.com,https://dev-admin.example.com
19
19
 
20
20
  DEV_CLIENT_LANDING_PORT=13000
21
- DEV_CLIENT_PLATFORM_PORT=13001
21
+ DEV_CLIENT_WEB_PORT=13001
22
22
  DEV_CLIENT_MOBILE_PORT=13002
23
23
  DEV_CLIENT_ADMIN_PORT=14000
24
24
 
25
25
  DEV_CLIENT_LANDING_VITE_API_BASE_URL=https://dev-api.example.com/api/v1
26
- DEV_CLIENT_PLATFORM_VITE_API_BASE_URL=https://dev-api.example.com/api/v1
26
+ DEV_CLIENT_WEB_VITE_API_BASE_URL=https://dev-api.example.com/api/v1
27
27
  DEV_CLIENT_MOBILE_VITE_API_BASE_URL=https://dev-api.example.com/api/v1
28
28
  DEV_CLIENT_ADMIN_VITE_API_BASE_URL=https://dev-api.example.com/api/v1
@@ -16,14 +16,14 @@ PROD_SERVER_MONGODB_URL=mongodb://mongo:27017
16
16
  PROD_SERVER_MONGODB_DATABASE=template
17
17
  PROD_SERVER_JWT_SECRET=change-me
18
18
  PROD_SERVER_ACCESS_TOKEN_TTL_MINUTES=120
19
- PROD_SERVER_CORS_ORIGINS=https://landing.example.com,https://platform.example.com,https://mobile.example.com,https://admin.example.com
19
+ PROD_SERVER_CORS_ORIGINS=https://landing.example.com,https://web.example.com,https://mobile.example.com,https://admin.example.com
20
20
 
21
21
  PROD_CLIENT_LANDING_PORT=23000
22
- PROD_CLIENT_PLATFORM_PORT=23001
22
+ PROD_CLIENT_WEB_PORT=23001
23
23
  PROD_CLIENT_MOBILE_PORT=23002
24
24
  PROD_CLIENT_ADMIN_PORT=24000
25
25
 
26
26
  PROD_CLIENT_LANDING_VITE_API_BASE_URL=https://api.example.com/api/v1
27
- PROD_CLIENT_PLATFORM_VITE_API_BASE_URL=https://api.example.com/api/v1
27
+ PROD_CLIENT_WEB_VITE_API_BASE_URL=https://api.example.com/api/v1
28
28
  PROD_CLIENT_MOBILE_VITE_API_BASE_URL=https://api.example.com/api/v1
29
29
  PROD_CLIENT_ADMIN_VITE_API_BASE_URL=https://api.example.com/api/v1
@@ -30,6 +30,6 @@ docker compose --env-file infra/compose/.env.prod -f infra/compose/prod.yml up -
30
30
  - `infra/compose/dev.yml`, `infra/compose/prod.yml`은 dedicated host/runtime split이 필요할 때 쓰는 overlay이며, root compose baseline을 대체하는 문서 기준선은 아니다.
31
31
  - provider-first canonical delivery split은 `AWS edge/domain -> OpenStack backend compute -> AWS data plane`이고, 세부 구조는 `infra/terraform/README.md`를 기준으로 설명한다.
32
32
  - `VITE_API_BASE_URL`은 컨테이너 내부 DNS가 아니라 브라우저가 도달 가능한 API URL이어야 한다.
33
- - 포트 역할은 root compose baseline과 같은 순서를 따른다: landing, platform, mobile, admin, server/http.
33
+ - 포트 역할은 root compose baseline과 같은 순서를 따른다: landing, web, mobile, admin, server/http.
34
34
  - PROD 웹 앱은 `pnpm build + pnpm preview`로 기동한다.
35
35
  - OpenStack에서 자동 배포까지 묶고 싶으면 `infra/terraform/openstack/server` 또는 lower-level `openstack/dev`, `openstack/prod` root를 사용한다.
@@ -65,20 +65,20 @@ services:
65
65
  networks:
66
66
  - templates-dev
67
67
 
68
- client-platform:
68
+ client-web:
69
69
  build:
70
70
  context: ../..
71
- dockerfile: client/platform/Dockerfile
72
- container_name: templates-client-platform-dev
71
+ dockerfile: client/web/Dockerfile
72
+ container_name: templates-client-web-dev
73
73
  restart: unless-stopped
74
74
  depends_on:
75
75
  server:
76
76
  condition: service_started
77
77
  environment:
78
- VITE_API_BASE_URL: ${DEV_CLIENT_PLATFORM_VITE_API_BASE_URL}
78
+ VITE_API_BASE_URL: ${DEV_CLIENT_WEB_VITE_API_BASE_URL}
79
79
  PORT: 3001
80
80
  ports:
81
- - "${DEV_CLIENT_PLATFORM_PORT:-13001}:3001"
81
+ - "${DEV_CLIENT_WEB_PORT:-13001}:3001"
82
82
  networks:
83
83
  - templates-dev
84
84
 
@@ -43,7 +43,7 @@ services:
43
43
  MONGODB_DATABASE: ${PROD_SERVER_MONGODB_DATABASE:-template}
44
44
  JWT_SECRET: ${PROD_SERVER_JWT_SECRET:-change-me}
45
45
  ACCESS_TOKEN_TTL_MINUTES: ${PROD_SERVER_ACCESS_TOKEN_TTL_MINUTES:-120}
46
- CORS_ORIGINS: ${PROD_SERVER_CORS_ORIGINS:-https://landing.example.com,https://platform.example.com,https://mobile.example.com,https://admin.example.com}
46
+ CORS_ORIGINS: ${PROD_SERVER_CORS_ORIGINS:-https://landing.example.com,https://web.example.com,https://mobile.example.com,https://admin.example.com}
47
47
  ports:
48
48
  - "${PROD_SERVER_HTTP_PORT:-28000}:8000"
49
49
  networks:
@@ -66,20 +66,20 @@ services:
66
66
  networks:
67
67
  - templates-prod
68
68
 
69
- client-platform:
69
+ client-web:
70
70
  build:
71
71
  context: ../..
72
- dockerfile: client/platform/Dockerfile
73
- container_name: templates-client-platform-prod
72
+ dockerfile: client/web/Dockerfile
73
+ container_name: templates-client-web-prod
74
74
  restart: unless-stopped
75
75
  depends_on:
76
76
  server:
77
77
  condition: service_started
78
78
  command: ["sh", "-lc", "pnpm build && pnpm preview --host 0.0.0.0 --port 4301"]
79
79
  environment:
80
- VITE_API_BASE_URL: ${PROD_CLIENT_PLATFORM_VITE_API_BASE_URL}
80
+ VITE_API_BASE_URL: ${PROD_CLIENT_WEB_VITE_API_BASE_URL}
81
81
  ports:
82
- - "${PROD_CLIENT_PLATFORM_PORT:-23001}:4301"
82
+ - "${PROD_CLIENT_WEB_PORT:-23001}:4301"
83
83
  networks:
84
84
  - templates-prod
85
85
 
@@ -42,13 +42,13 @@ compose_env_content = <<-ENV
42
42
  DEV_SERVER_POSTGRES_URL=postgresql+psycopg://template:template@postgres:5432/template
43
43
  DEV_SERVER_JWT_SECRET=change-me
44
44
  DEV_SERVER_ACCESS_TOKEN_TTL_MINUTES=120
45
- DEV_SERVER_CORS_ORIGINS=https://dev-landing.example.com,https://dev-platform.example.com,https://dev-mobile.example.com,https://dev-admin.example.com
45
+ DEV_SERVER_CORS_ORIGINS=https://dev-landing.example.com,https://dev-web.example.com,https://dev-mobile.example.com,https://dev-admin.example.com
46
46
  DEV_CLIENT_LANDING_PORT=13000
47
- DEV_CLIENT_PLATFORM_PORT=13001
47
+ DEV_CLIENT_WEB_PORT=13001
48
48
  DEV_CLIENT_MOBILE_PORT=13002
49
49
  DEV_CLIENT_ADMIN_PORT=14000
50
50
  DEV_CLIENT_LANDING_VITE_API_BASE_URL=https://dev-api.example.com/api/v1
51
- DEV_CLIENT_PLATFORM_VITE_API_BASE_URL=https://dev-api.example.com/api/v1
51
+ DEV_CLIENT_WEB_VITE_API_BASE_URL=https://dev-api.example.com/api/v1
52
52
  DEV_CLIENT_MOBILE_VITE_API_BASE_URL=https://dev-api.example.com/api/v1
53
53
  DEV_CLIENT_ADMIN_VITE_API_BASE_URL=https://dev-api.example.com/api/v1
54
54
  ENV
@@ -43,13 +43,13 @@ compose_env_content = <<-ENV
43
43
  PROD_SERVER_POSTGRES_URL=postgresql+psycopg://template:template@postgres:5432/template
44
44
  PROD_SERVER_JWT_SECRET=change-me
45
45
  PROD_SERVER_ACCESS_TOKEN_TTL_MINUTES=120
46
- PROD_SERVER_CORS_ORIGINS=https://landing.example.com,https://platform.example.com,https://mobile.example.com,https://admin.example.com
46
+ PROD_SERVER_CORS_ORIGINS=https://landing.example.com,https://web.example.com,https://mobile.example.com,https://admin.example.com
47
47
  PROD_CLIENT_LANDING_PORT=23000
48
- PROD_CLIENT_PLATFORM_PORT=23001
48
+ PROD_CLIENT_WEB_PORT=23001
49
49
  PROD_CLIENT_MOBILE_PORT=23002
50
50
  PROD_CLIENT_ADMIN_PORT=24000
51
51
  PROD_CLIENT_LANDING_VITE_API_BASE_URL=https://api.example.com/api/v1
52
- PROD_CLIENT_PLATFORM_VITE_API_BASE_URL=https://api.example.com/api/v1
52
+ PROD_CLIENT_WEB_VITE_API_BASE_URL=https://api.example.com/api/v1
53
53
  PROD_CLIENT_MOBILE_VITE_API_BASE_URL=https://api.example.com/api/v1
54
54
  PROD_CLIENT_ADMIN_VITE_API_BASE_URL=https://api.example.com/api/v1
55
55
  ENV
package/lib/scaffold.mjs CHANGED
@@ -11,11 +11,11 @@ export const TEMPLATE_CONFIG = {
11
11
  composeApiVar: "CLIENT_LANDING_VITE_API_BASE_URL",
12
12
  defaultPort: 3000,
13
13
  },
14
- platform: {
15
- id: "platform",
16
- serviceName: "client-platform",
17
- composePortVar: "CLIENT_PLATFORM_PORT",
18
- composeApiVar: "CLIENT_PLATFORM_VITE_API_BASE_URL",
14
+ web: {
15
+ id: "web",
16
+ serviceName: "client-web",
17
+ composePortVar: "CLIENT_WEB_PORT",
18
+ composeApiVar: "CLIENT_WEB_VITE_API_BASE_URL",
19
19
  defaultPort: 3001,
20
20
  },
21
21
  mobile: {
@@ -112,10 +112,10 @@ export function parseArgs(argv) {
112
112
  export function usage() {
113
113
  return [
114
114
  "Usage:",
115
- " agentic-dev init <target-dir> --template <landing|platform|mobile|admin>",
115
+ " agentic-dev init <target-dir> --template <landing|web|mobile|admin>",
116
116
  "",
117
117
  "Examples:",
118
- " npx agentic-dev init my-app --template platform",
118
+ " npx agentic-dev init my-app --template web",
119
119
  " npx agentic-dev my-app --template mobile",
120
120
  "",
121
121
  "Options:",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-dev",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Scaffold an agentic template repo with the selected frontend surface and shared toolchain assets.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.32.0",
@@ -28,7 +28,7 @@
28
28
  "pnpm-workspace.yaml"
29
29
  ],
30
30
  "scripts": {
31
- "smoke:init": "node ./bin/agentic-dev.mjs init ./.tmp-agentic-smoke --template platform --yes --force"
31
+ "smoke:init": "node ./bin/agentic-dev.mjs init ./.tmp-agentic-smoke --template web --yes --force"
32
32
  },
33
33
  "keywords": [
34
34
  "agentic",
@@ -12,7 +12,7 @@ ROOT = Path(__file__).resolve().parents[2]
12
12
 
13
13
  SERVICE_DOCS = {
14
14
  "mobile": ROOT / "sdd/03_build/01_feature/service/mobile_surface.md",
15
- "platform": ROOT / "sdd/03_build/01_feature/service/platform_surface.md",
15
+ "web": ROOT / "sdd/03_build/01_feature/service/web_surface.md",
16
16
  "admin": ROOT / "sdd/03_build/01_feature/service/admin_surface.md",
17
17
  "landing": ROOT / "sdd/03_build/01_feature/service/landing_surface.md",
18
18
  }
@@ -59,14 +59,14 @@ def ast_similarity() -> tuple[int, list[str]]:
59
59
  else:
60
60
  findings.append("mobile surface summary does not reflect the real provider/router/shell chain.")
61
61
 
62
- platform = read(SERVICE_DOCS["platform"])
62
+ web = read(SERVICE_DOCS["web"])
63
63
  if contains_all(
64
- platform,
64
+ web,
65
65
  [
66
- "client/platform/src/main.tsx",
66
+ "client/web/src/main.tsx",
67
67
  "AuthProvider",
68
68
  "BrowserRouter",
69
- "client/platform/src/app/App.tsx",
69
+ "client/web/src/app/App.tsx",
70
70
  "ProtectedRoute",
71
71
  "AppShell",
72
72
  "DashboardPage",
@@ -75,7 +75,7 @@ def ast_similarity() -> tuple[int, list[str]]:
75
75
  ):
76
76
  points += 2.5
77
77
  else:
78
- findings.append("platform surface summary does not reflect the real app shell route tree.")
78
+ findings.append("web surface summary does not reflect the real app shell route tree.")
79
79
 
80
80
  admin = read(SERVICE_DOCS["admin"])
81
81
  if contains_all(
@@ -139,9 +139,9 @@ def implementation_traceability() -> tuple[int, list[str]]:
139
139
  else:
140
140
  findings.append("mobile surface summary does not trace route leaves to backend contract leaves.")
141
141
 
142
- platform = read(SERVICE_DOCS["platform"])
142
+ web = read(SERVICE_DOCS["web"])
143
143
  if contains_all(
144
- platform,
144
+ web,
145
145
  [
146
146
  "server/main.py",
147
147
  "server/api/http/app.py",
@@ -153,7 +153,7 @@ def implementation_traceability() -> tuple[int, list[str]]:
153
153
  ):
154
154
  points += 2.0
155
155
  else:
156
- findings.append("platform surface summary does not trace dashboard and orders routes to backend contracts.")
156
+ findings.append("web surface summary does not trace dashboard and orders routes to backend contracts.")
157
157
 
158
158
  admin = read(SERVICE_DOCS["admin"])
159
159
  if contains_all(
@@ -19,7 +19,7 @@
19
19
 
20
20
  | Actor | Description | Appears In |
21
21
  | --- | --- | --- |
22
- | `Platform User` | platform 서비스에서 주문/운영 기능에 접근하기 위해 인증 세션을 발급받는 사용자다. | `AUT-F001` |
22
+ | `Web User` | web 서비스에서 주문/운영 기능에 접근하기 위해 인증 세션을 발급받는 사용자다. | `AUT-F001` |
23
23
  | `Mobile Operator` | mobile 서비스에서 이행 작업을 수행하기 위해 로그인하는 현장 운영자다. | `AUT-F001` |
24
24
  | `Admin Operator` | admin 서비스에서 카탈로그, 재고, 사용자 운영 명령을 수행하기 위해 관리자 세션을 발급받는 주체다. | `AUT-F001` |
25
25
  | `Landing Member` | landing 서비스에서 회원 전용 자원이나 개인화 동작을 사용하기 위해 로그인하는 사용자다. | `AUT-F001` |
@@ -48,7 +48,7 @@
48
48
 
49
49
  | Feature Code | Use Case | Actor | Bounded Context | Aggregate / Model | Type | Preconditions | Domain Outcome | Invariant / Business Rule |
50
50
  | --- | --- | --- | --- | --- | --- | --- | --- | --- |
51
- | `AUT-F001` | 이메일/비밀번호로 로그인하고 access token을 발급한다 | Platform User, Mobile Operator, Admin Operator, Landing Member | Authentication & Session | `LoginCommand`, `AuthToken`, `AuthAccountRecord` | Command | 이메일과 비밀번호가 전달되고, 인증 계정 저장소에 해당 사용자가 존재해야 한다 | access token과 `user_id`가 발급된다 | credential이 일치하지 않으면 `401 Invalid credentials`를 반환한다 |
51
+ | `AUT-F001` | 이메일/비밀번호로 로그인하고 access token을 발급한다 | Web User, Mobile Operator, Admin Operator, Landing Member | Authentication & Session | `LoginCommand`, `AuthToken`, `AuthAccountRecord` | Command | 이메일과 비밀번호가 전달되고, 인증 계정 저장소에 해당 사용자가 존재해야 한다 | access token과 `user_id`가 발급된다 | credential이 일치하지 않으면 `401 Invalid credentials`를 반환한다 |
52
52
  | `AUT-F002` | bearer token으로 현재 세션 사용자를 해석한다 | Authenticated Client | Authentication & Session | `AuthToken`, `AuthenticatedUser`, `AuthAccountRecord` | Query | 유효한 bearer token이 전달되고 token subject가 인증 계정 저장소에 존재해야 한다 | 현재 사용자 summary를 반환한다 | token이 위조되었거나 subject 사용자가 없으면 `401 Invalid token`을 반환한다 |
53
53
 
54
54
  ## 7. Notes
@@ -21,7 +21,7 @@
21
21
  | --- | --- | --- |
22
22
  | `Landing Visitor` | 비로그인 상태로 공개 상품 카탈로그와 상품 상세를 탐색하는 방문자다. | `CAT-F001`, `CAT-F002` |
23
23
  | `Landing Member` | 로그인된 landing 회원으로 공개 상품을 둘러보고 구매 전 탐색을 수행하는 사용자다. | `CAT-F001`, `CAT-F002` |
24
- | `Platform User` | platform 서비스에서 주문 생성이나 운영 판단을 위해 상품 정보를 조회하는 내부 사용자다. | `CAT-F001`, `CAT-F002` |
24
+ | `Web User` | web 서비스에서 주문 생성이나 운영 판단을 위해 상품 정보를 조회하는 내부 사용자다. | `CAT-F001`, `CAT-F002` |
25
25
  | `Admin Operator` | admin 서비스에서 상품을 등록, 수정, 상태 변경하는 운영 관리자다. | `CAT-F003`, `CAT-F004`, `CAT-F005` |
26
26
 
27
27
  ## 4. Bounded Context Summary
@@ -49,8 +49,8 @@
49
49
 
50
50
  | Feature Code | Use Case | Actor | Bounded Context | Aggregate / Model | Type | Preconditions | Domain Outcome | Invariant / Business Rule |
51
51
  | --- | --- | --- | --- | --- | --- | --- | --- | --- |
52
- | `CAT-F001` | 상품 카탈로그 목록을 조회한다 | Landing Visitor, Landing Member, Platform User | Product Catalog | `ProductSummary`, `ProductRecord` | Query | 상품 bootstrap 데이터가 존재해야 한다 | 공개 가능한 상품 목록을 필터와 검색 조건에 맞게 반환한다 | `status`, `category`, `q` 조건은 모두 현재 카탈로그 집합 안에서 계산한다 |
53
- | `CAT-F002` | 단일 상품 상세를 조회한다 | Landing Visitor, Landing Member, Platform User | Product Catalog | `ProductDetail`, `ProductRecord` | Query | 요청한 `product_id`가 저장소에 존재해야 한다 | 상세 페이지 구성을 위한 상품 전체 속성을 반환한다 | 존재하지 않는 `product_id`면 `404 Catalog product not found`를 반환한다 |
52
+ | `CAT-F001` | 상품 카탈로그 목록을 조회한다 | Landing Visitor, Landing Member, Web User | Product Catalog | `ProductSummary`, `ProductRecord` | Query | 상품 bootstrap 데이터가 존재해야 한다 | 공개 가능한 상품 목록을 필터와 검색 조건에 맞게 반환한다 | `status`, `category`, `q` 조건은 모두 현재 카탈로그 집합 안에서 계산한다 |
53
+ | `CAT-F002` | 단일 상품 상세를 조회한다 | Landing Visitor, Landing Member, Web User | Product Catalog | `ProductDetail`, `ProductRecord` | Query | 요청한 `product_id`가 저장소에 존재해야 한다 | 상세 페이지 구성을 위한 상품 전체 속성을 반환한다 | 존재하지 않는 `product_id`면 `404 Catalog product not found`를 반환한다 |
54
54
  | `CAT-F003` | 관리자가 새 상품을 등록한다 | Admin Operator | Product Catalog | `CreateProductCommand`, `ProductDetail`, `ProductRecord` | Command | 관리자 토큰이 유효하고 slug, 이름, 가격, variant 정보가 전달되어야 한다 | 새 상품 레코드가 생성되어 카탈로그 목록에 합류한다 | `slug`는 카탈로그 내에서 유일해야 하며 variant는 최소 1개 이상이어야 한다 |
55
55
  | `CAT-F004` | 관리자가 상품 속성을 수정한다 | Admin Operator | Product Catalog | `UpdateProductCommand`, `ProductDetail`, `ProductRecord` | Command | 관리자 토큰이 유효하고 요청한 `product_id`가 존재해야 한다 | 상품 속성이 부분 갱신되고 `updated_at`이 갱신된다 | 빈 수정 요청은 `400 No catalog product fields provided`, 중복 slug는 `409`를 반환한다 |
56
56
  | `CAT-F005` | 관리자가 상품 상태를 변경한다 | Admin Operator | Product Catalog | `UpdateProductStatusCommand`, `ProductDetail`, `ProductRecord` | Command | 관리자 토큰이 유효하고 요청한 `product_id`가 존재해야 한다 | 상품 `status`가 `draft`, `active`, `archived` 중 하나로 전환된다 | 존재하지 않는 `product_id`면 `404 Catalog product not found`를 반환한다 |
@@ -4,12 +4,12 @@
4
4
 
5
5
  ## 1. Purpose
6
6
 
7
- `orders` bounded context가 제공하는 플랫폼 주문 현황과 관리자 운영 큐 기능을 구현 기준으로 정리한다.
7
+ `orders` bounded context가 제공하는 web 주문 현황과 관리자 운영 큐 기능을 구현 기준으로 정리한다.
8
8
 
9
9
  ## 2. Scope
10
10
 
11
11
  - 포함 범위:
12
- - platform 주문 overview/list read model과 주문 생성, 상태 전이 command
12
+ - web 주문 overview/list read model과 주문 생성, 상태 전이 command
13
13
  - admin 주문 overview/queue read model
14
14
  - 제외 범위:
15
15
  - 외부 결제 게이트웨이 정산이나 배송사 연동
@@ -19,7 +19,7 @@
19
19
 
20
20
  | Actor | Description | Appears In |
21
21
  | --- | --- | --- |
22
- | `Platform User` | platform 서비스에서 주문 현황을 조회하고 신규 주문 생성이나 주문 상태 갱신을 수행하는 운영 사용자다. | `ORD-F001`, `ORD-F002`, `ORD-F003`, `ORD-F004` |
22
+ | `Web User` | web 서비스에서 주문 현황을 조회하고 신규 주문 생성이나 주문 상태 갱신을 수행하는 운영 사용자다. | `ORD-F001`, `ORD-F002`, `ORD-F003`, `ORD-F004` |
23
23
  | `Admin Operator` | admin 서비스에서 주문 KPI와 운영 큐를 모니터링하는 관리자다. | `ORD-F005`, `ORD-F006` |
24
24
 
25
25
  ## 4. Bounded Context Summary
@@ -37,8 +37,8 @@
37
37
  | Aggregate / Model | Role |
38
38
  | --- | --- |
39
39
  | `OrderRecord` | bootstrap 기반 주문 원본 |
40
- | `OrderOverview` | 플랫폼 dashboard 요약 읽기 모델 |
41
- | `OrderSummary` | 플랫폼 orders 목록 읽기 모델 |
40
+ | `OrderOverview` | web dashboard 요약 읽기 모델 |
41
+ | `OrderSummary` | web orders 목록 읽기 모델 |
42
42
  | `CreateOrderCommand` | 주문 생성 명령 |
43
43
  | `UpdateOrderStatusCommand` | 주문 상태 전이 명령 |
44
44
  | `OrderStatusTransition` | 주문 상태 전이 결과 |
@@ -49,15 +49,15 @@
49
49
 
50
50
  | Feature Code | Use Case | Actor | Bounded Context | Aggregate / Model | Type | Preconditions | Domain Outcome | Invariant / Business Rule |
51
51
  | --- | --- | --- | --- | --- | --- | --- | --- | --- |
52
- | `ORD-F001` | 플랫폼 주문 overview를 조회한다 | Platform User | Order Operations | `OrderOverview`, `OrderRecord` | Query | 인증 토큰이 유효하고 주문 bootstrap 데이터가 존재해야 한다 | 주문 카드, 최근 활동, 선택 주문 상세를 함께 반환한다 | overview는 최근 활동 3건과 선택 주문 1건을 항상 포함한다 |
53
- | `ORD-F002` | 플랫폼 주문 목록을 조회한다 | Platform User | Order Operations | `OrderSummary`, `OrderRecord` | Query | 인증 토큰이 유효하고 주문 bootstrap 데이터가 존재해야 한다 | 주문 목록을 반환한다 | 목록 행은 `id`, `product_name`, `customer_name`, `status`를 유지한다 |
54
- | `ORD-F003` | 신규 주문을 생성한다 | Platform User | Order Operations | `CreateOrderCommand`, `OrderRecord` | Command | 인증 토큰이 유효하고 제품, 고객, 판매자, 금액 정보가 전달되어야 한다 | 새 `OrderRecord`가 생성되어 목록과 overview에 반영된다 | 새 주문은 문자열 ID를 부여받고 `Pending`과 `Queued`를 기본 상태로 사용한다 |
55
- | `ORD-F004` | 주문의 결제/이행 상태를 변경한다 | Platform User | Order Operations | `UpdateOrderStatusCommand`, `OrderStatusTransition`, `OrderRecord` | Command | 인증 토큰이 유효하고 요청한 `order_id`가 존재해야 한다 | 주문의 `status`, `fulfillment_status`, `stage`가 변경된다 | 존재하지 않는 `order_id`면 `404`를 반환한다 |
56
- | `ORD-F005` | 관리자용 주문 overview를 조회한다 | Admin Operator | Order Operations | `AdminOrderOverview`, `OrderRecord` | Query | 관리자 토큰이 유효하고 주문 bootstrap 데이터가 존재해야 한다 | 관리자 KPI와 stage 현황을 반환한다 | admin surface는 platform surface와 다른 운영형 read model을 사용한다 |
52
+ | `ORD-F001` | web 주문 overview를 조회한다 | Web User | Order Operations | `OrderOverview`, `OrderRecord` | Query | 인증 토큰이 유효하고 주문 bootstrap 데이터가 존재해야 한다 | 주문 카드, 최근 활동, 선택 주문 상세를 함께 반환한다 | overview는 최근 활동 3건과 선택 주문 1건을 항상 포함한다 |
53
+ | `ORD-F002` | web 주문 목록을 조회한다 | Web User | Order Operations | `OrderSummary`, `OrderRecord` | Query | 인증 토큰이 유효하고 주문 bootstrap 데이터가 존재해야 한다 | 주문 목록을 반환한다 | 목록 행은 `id`, `product_name`, `customer_name`, `status`를 유지한다 |
54
+ | `ORD-F003` | 신규 주문을 생성한다 | Web User | Order Operations | `CreateOrderCommand`, `OrderRecord` | Command | 인증 토큰이 유효하고 제품, 고객, 판매자, 금액 정보가 전달되어야 한다 | 새 `OrderRecord`가 생성되어 목록과 overview에 반영된다 | 새 주문은 문자열 ID를 부여받고 `Pending`과 `Queued`를 기본 상태로 사용한다 |
55
+ | `ORD-F004` | 주문의 결제/이행 상태를 변경한다 | Web User | Order Operations | `UpdateOrderStatusCommand`, `OrderStatusTransition`, `OrderRecord` | Command | 인증 토큰이 유효하고 요청한 `order_id`가 존재해야 한다 | 주문의 `status`, `fulfillment_status`, `stage`가 변경된다 | 존재하지 않는 `order_id`면 `404`를 반환한다 |
56
+ | `ORD-F005` | 관리자용 주문 overview를 조회한다 | Admin Operator | Order Operations | `AdminOrderOverview`, `OrderRecord` | Query | 관리자 토큰이 유효하고 주문 bootstrap 데이터가 존재해야 한다 | 관리자 KPI와 stage 현황을 반환한다 | admin surface는 web surface와 다른 운영형 read model을 사용한다 |
57
57
  | `ORD-F006` | 관리자용 거래 큐를 조회한다 | Admin Operator | Order Operations | `AdminQueueItem`, `OrderRecord` | Query | 관리자 토큰이 유효하고 주문 bootstrap 데이터가 존재해야 한다 | 주문별 운영 큐 행을 반환한다 | 큐 행은 `order_id`, `product_name`, `customer_name`, `status`, `sla`를 유지한다 |
58
58
 
59
59
  ## 7. Notes
60
60
 
61
- - `orders`는 platform surface와 admin surface에 서로 다른 read model을 제공한다.
61
+ - `orders`는 web surface와 admin surface에 서로 다른 read model을 제공한다.
62
62
  - 운영 알람 feed는 별도 `alerts` context가 소유하고, `orders`는 주문 자체 read/write 모델만 유지한다.
63
63
  - template baseline의 주문 상태 전이는 내부 mutation semantics까지만 다루며 외부 결제/이벤트 연동은 포함하지 않는다.
@@ -1,9 +1,9 @@
1
1
  # Screen Planning
2
2
 
3
3
  - screen code format: `{SERVICE}-S{NNN}`
4
- - canonical service code: `PLT`, `ADM`, `MOB`, `LND`
4
+ - canonical service code: `WEB`, `ADM`, `MOB`, `LND`
5
5
 
6
- - [platform_screen_spec.pdf](./platform_screen_spec.pdf)
6
+ - [web_screen_spec.pdf](./web_screen_spec.pdf)
7
7
  - [admin_screen_spec.pdf](./admin_screen_spec.pdf)
8
8
  - [mobile_screen_spec.pdf](./mobile_screen_spec.pdf)
9
9
  - [landing_screen_spec.pdf](./landing_screen_spec.pdf)