agentic-dev 0.2.9 → 0.2.11

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 (291) hide show
  1. package/README.md +23 -8
  2. package/bin/agentic-dev.mjs +692 -55
  3. package/lib/scaffold.mjs +109 -6
  4. package/package.json +1 -1
  5. package/client/admin/.dockerignore +0 -3
  6. package/client/admin/.env.example +0 -1
  7. package/client/admin/Dockerfile +0 -16
  8. package/client/admin/Dockerfile.dev +0 -18
  9. package/client/admin/README.md +0 -20
  10. package/client/admin/index.html +0 -12
  11. package/client/admin/package.json +0 -41
  12. package/client/admin/postcss.config.js +0 -6
  13. package/client/admin/scripts/ui-parity-admin-adapter.mjs +0 -65
  14. package/client/admin/src/api/alerts.ts +0 -33
  15. package/client/admin/src/api/client.ts +0 -71
  16. package/client/admin/src/api/orders.ts +0 -33
  17. package/client/admin/src/api/support.ts +0 -11
  18. package/client/admin/src/app/App.tsx +0 -23
  19. package/client/admin/src/auth/AuthProvider.tsx +0 -122
  20. package/client/admin/src/auth/ProtectedRoute.tsx +0 -22
  21. package/client/admin/src/auth/auth-client.ts +0 -38
  22. package/client/admin/src/auth/types.ts +0 -18
  23. package/client/admin/src/components/AdminNotificationsDrawer.tsx +0 -162
  24. package/client/admin/src/components/AdminShell.tsx +0 -76
  25. package/client/admin/src/components/ui/button.tsx +0 -34
  26. package/client/admin/src/components/ui/input.tsx +0 -21
  27. package/client/admin/src/lib/cn.ts +0 -6
  28. package/client/admin/src/lib/specRouteCatalog.json +0 -30
  29. package/client/admin/src/lib/specScreens.json +0 -22
  30. package/client/admin/src/main.tsx +0 -17
  31. package/client/admin/src/pages/AdminDashboardPage.tsx +0 -171
  32. package/client/admin/src/pages/AdminLoginPage.tsx +0 -75
  33. package/client/admin/src/pages/AdminQueuePage.tsx +0 -107
  34. package/client/admin/src/pages/AdminSupportPage.tsx +0 -61
  35. package/client/admin/src/styles/globals.css +0 -17
  36. package/client/admin/src/theme-vars.ts +0 -18
  37. package/client/admin/src/theme.ts +0 -25
  38. package/client/admin/src/vite-env.d.ts +0 -1
  39. package/client/admin/tailwind.config.js +0 -8
  40. package/client/admin/tsconfig.json +0 -25
  41. package/client/admin/vite.config.ts +0 -12
  42. package/client/landing/.dockerignore +0 -3
  43. package/client/landing/.env.example +0 -1
  44. package/client/landing/Dockerfile +0 -16
  45. package/client/landing/Dockerfile.dev +0 -18
  46. package/client/landing/README.md +0 -18
  47. package/client/landing/index.html +0 -12
  48. package/client/landing/package.json +0 -41
  49. package/client/landing/postcss.config.js +0 -6
  50. package/client/landing/scripts/ui-parity-landing-adapter.mjs +0 -65
  51. package/client/landing/src/App.tsx +0 -21
  52. package/client/landing/src/api/catalog.ts +0 -30
  53. package/client/landing/src/api/client.ts +0 -30
  54. package/client/landing/src/auth/AuthProvider.tsx +0 -122
  55. package/client/landing/src/auth/ProtectedRoute.tsx +0 -22
  56. package/client/landing/src/auth/auth-client.ts +0 -38
  57. package/client/landing/src/auth/types.ts +0 -18
  58. package/client/landing/src/components/LandingShell.tsx +0 -34
  59. package/client/landing/src/lib/specRouteCatalog.json +0 -23
  60. package/client/landing/src/lib/specScreens.json +0 -17
  61. package/client/landing/src/main.tsx +0 -17
  62. package/client/landing/src/pages/LandingHomePage.tsx +0 -215
  63. package/client/landing/src/pages/LandingLoginPage.tsx +0 -90
  64. package/client/landing/src/pages/LandingWorkspacePage.tsx +0 -126
  65. package/client/landing/src/styles/globals.css +0 -17
  66. package/client/landing/src/theme-vars.ts +0 -16
  67. package/client/landing/src/theme.ts +0 -21
  68. package/client/landing/src/vite-env.d.ts +0 -1
  69. package/client/landing/tailwind.config.js +0 -8
  70. package/client/landing/tsconfig.json +0 -25
  71. package/client/landing/vite.config.ts +0 -12
  72. package/client/mobile/.dockerignore +0 -2
  73. package/client/mobile/.env.example +0 -1
  74. package/client/mobile/Dockerfile +0 -16
  75. package/client/mobile/Dockerfile.dev +0 -18
  76. package/client/mobile/README.md +0 -19
  77. package/client/mobile/index.html +0 -12
  78. package/client/mobile/package.json +0 -42
  79. package/client/mobile/postcss.config.js +0 -6
  80. package/client/mobile/scripts/ui-parity-mobile-adapter.mjs +0 -67
  81. package/client/mobile/src/App.tsx +0 -1
  82. package/client/mobile/src/api/client.ts +0 -62
  83. package/client/mobile/src/api/fulfillment.ts +0 -55
  84. package/client/mobile/src/api/shipping.ts +0 -56
  85. package/client/mobile/src/app/App.tsx +0 -23
  86. package/client/mobile/src/auth/AuthProvider.tsx +0 -122
  87. package/client/mobile/src/auth/ProtectedRoute.tsx +0 -27
  88. package/client/mobile/src/auth/auth-client.ts +0 -38
  89. package/client/mobile/src/auth/types.ts +0 -18
  90. package/client/mobile/src/components/InShell.tsx +0 -74
  91. package/client/mobile/src/components/ui/button.tsx +0 -35
  92. package/client/mobile/src/components/ui/card.tsx +0 -15
  93. package/client/mobile/src/components/ui/input.tsx +0 -21
  94. package/client/mobile/src/lib/cn.ts +0 -6
  95. package/client/mobile/src/lib/specRouteCatalog.json +0 -26
  96. package/client/mobile/src/lib/specScreens.json +0 -22
  97. package/client/mobile/src/lib/useSpeechRecognitionInput.ts +0 -271
  98. package/client/mobile/src/main.tsx +0 -17
  99. package/client/mobile/src/pages/DashboardPage.tsx +0 -172
  100. package/client/mobile/src/pages/FulfillmentPage.tsx +0 -138
  101. package/client/mobile/src/pages/LoginPage.tsx +0 -74
  102. package/client/mobile/src/pages/ShippingPage.tsx +0 -338
  103. package/client/mobile/src/styles/globals.css +0 -23
  104. package/client/mobile/src/theme-vars.ts +0 -16
  105. package/client/mobile/src/theme.ts +0 -21
  106. package/client/mobile/src/vite-env.d.ts +0 -1
  107. package/client/mobile/tailwind.config.js +0 -8
  108. package/client/mobile/tsconfig.json +0 -25
  109. package/client/mobile/vite.config.ts +0 -12
  110. package/client/web/.dockerignore +0 -3
  111. package/client/web/.env.example +0 -1
  112. package/client/web/Dockerfile +0 -16
  113. package/client/web/Dockerfile.dev +0 -18
  114. package/client/web/README.md +0 -47
  115. package/client/web/index.html +0 -12
  116. package/client/web/package.json +0 -42
  117. package/client/web/postcss.config.js +0 -6
  118. package/client/web/scripts/ui-parity-web-adapter.mjs +0 -66
  119. package/client/web/src/api/client.ts +0 -30
  120. package/client/web/src/api/orders.ts +0 -42
  121. package/client/web/src/app/App.tsx +0 -21
  122. package/client/web/src/auth/AuthProvider.tsx +0 -122
  123. package/client/web/src/auth/ProtectedRoute.tsx +0 -22
  124. package/client/web/src/auth/auth-client.ts +0 -38
  125. package/client/web/src/auth/types.ts +0 -18
  126. package/client/web/src/components/AppShell.tsx +0 -59
  127. package/client/web/src/components/ui/button.tsx +0 -35
  128. package/client/web/src/components/ui/card.tsx +0 -7
  129. package/client/web/src/components/ui/input.tsx +0 -21
  130. package/client/web/src/lib/cn.ts +0 -6
  131. package/client/web/src/lib/specRouteCatalog.json +0 -23
  132. package/client/web/src/lib/specScreens.json +0 -17
  133. package/client/web/src/main.tsx +0 -17
  134. package/client/web/src/pages/DashboardPage.tsx +0 -158
  135. package/client/web/src/pages/LoginPage.tsx +0 -72
  136. package/client/web/src/pages/OrdersPage.tsx +0 -123
  137. package/client/web/src/styles/globals.css +0 -17
  138. package/client/web/src/theme-vars.ts +0 -18
  139. package/client/web/src/theme.ts +0 -25
  140. package/client/web/src/vite-env.d.ts +0 -1
  141. package/client/web/tailwind.config.js +0 -8
  142. package/client/web/tsconfig.json +0 -25
  143. package/client/web/vite.config.ts +0 -12
  144. package/server/.dockerignore +0 -4
  145. package/server/.env.example +0 -19
  146. package/server/Dockerfile +0 -22
  147. package/server/Dockerfile.dev +0 -19
  148. package/server/README.md +0 -33
  149. package/server/__init__.py +0 -0
  150. package/server/api/__init__.py +0 -1
  151. package/server/api/http/__init__.py +0 -4
  152. package/server/api/http/app.py +0 -53
  153. package/server/api/http/router.py +0 -24
  154. package/server/config.py +0 -52
  155. package/server/contexts/__init__.py +0 -12
  156. package/server/contexts/alerts/__init__.py +0 -1
  157. package/server/contexts/alerts/application/__init__.py +0 -13
  158. package/server/contexts/alerts/application/services.py +0 -41
  159. package/server/contexts/alerts/contracts/__init__.py +0 -3
  160. package/server/contexts/alerts/contracts/http/__init__.py +0 -3
  161. package/server/contexts/alerts/contracts/http/router.py +0 -37
  162. package/server/contexts/alerts/domain/__init__.py +0 -15
  163. package/server/contexts/alerts/domain/models.py +0 -29
  164. package/server/contexts/alerts/infrastructure/__init__.py +0 -11
  165. package/server/contexts/alerts/infrastructure/repository.py +0 -41
  166. package/server/contexts/auth/__init__.py +0 -1
  167. package/server/contexts/auth/application/__init__.py +0 -3
  168. package/server/contexts/auth/application/ports.py +0 -10
  169. package/server/contexts/auth/application/services.py +0 -64
  170. package/server/contexts/auth/contracts/__init__.py +0 -4
  171. package/server/contexts/auth/contracts/http/__init__.py +0 -4
  172. package/server/contexts/auth/contracts/http/dependencies.py +0 -37
  173. package/server/contexts/auth/contracts/http/router.py +0 -19
  174. package/server/contexts/auth/domain/__init__.py +0 -3
  175. package/server/contexts/auth/domain/models.py +0 -24
  176. package/server/contexts/auth/infrastructure/__init__.py +0 -4
  177. package/server/contexts/auth/infrastructure/adapters/memory.py +0 -19
  178. package/server/contexts/auth/infrastructure/adapters/mongodb.py +0 -24
  179. package/server/contexts/auth/infrastructure/adapters/sqlalchemy.py +0 -74
  180. package/server/contexts/auth/infrastructure/repository.py +0 -28
  181. package/server/contexts/catalog/__init__.py +0 -1
  182. package/server/contexts/catalog/application/__init__.py +0 -28
  183. package/server/contexts/catalog/application/ports.py +0 -15
  184. package/server/contexts/catalog/application/services.py +0 -154
  185. package/server/contexts/catalog/contracts/__init__.py +0 -3
  186. package/server/contexts/catalog/contracts/http/__init__.py +0 -3
  187. package/server/contexts/catalog/contracts/http/router.py +0 -60
  188. package/server/contexts/catalog/domain/__init__.py +0 -45
  189. package/server/contexts/catalog/domain/models.py +0 -113
  190. package/server/contexts/catalog/infrastructure/__init__.py +0 -4
  191. package/server/contexts/catalog/infrastructure/adapters/memory.py +0 -62
  192. package/server/contexts/catalog/infrastructure/repository.py +0 -8
  193. package/server/contexts/fulfillment/__init__.py +0 -1
  194. package/server/contexts/fulfillment/application/__init__.py +0 -13
  195. package/server/contexts/fulfillment/application/ports.py +0 -20
  196. package/server/contexts/fulfillment/application/services.py +0 -85
  197. package/server/contexts/fulfillment/contracts/__init__.py +0 -3
  198. package/server/contexts/fulfillment/contracts/http/__init__.py +0 -3
  199. package/server/contexts/fulfillment/contracts/http/router.py +0 -40
  200. package/server/contexts/fulfillment/domain/__init__.py +0 -25
  201. package/server/contexts/fulfillment/domain/models.py +0 -73
  202. package/server/contexts/fulfillment/infrastructure/__init__.py +0 -13
  203. package/server/contexts/fulfillment/infrastructure/adapters/memory.py +0 -43
  204. package/server/contexts/fulfillment/infrastructure/repository.py +0 -97
  205. package/server/contexts/health/__init__.py +0 -1
  206. package/server/contexts/health/application/__init__.py +0 -3
  207. package/server/contexts/health/application/services.py +0 -2
  208. package/server/contexts/health/contracts/__init__.py +0 -3
  209. package/server/contexts/health/contracts/http/__init__.py +0 -3
  210. package/server/contexts/health/contracts/http/router.py +0 -10
  211. package/server/contexts/inventory/__init__.py +0 -1
  212. package/server/contexts/inventory/application/__init__.py +0 -28
  213. package/server/contexts/inventory/application/ports.py +0 -11
  214. package/server/contexts/inventory/application/services.py +0 -214
  215. package/server/contexts/inventory/contracts/__init__.py +0 -3
  216. package/server/contexts/inventory/contracts/http/__init__.py +0 -3
  217. package/server/contexts/inventory/contracts/http/router.py +0 -82
  218. package/server/contexts/inventory/domain/__init__.py +0 -33
  219. package/server/contexts/inventory/domain/models.py +0 -93
  220. package/server/contexts/inventory/infrastructure/__init__.py +0 -4
  221. package/server/contexts/inventory/infrastructure/adapters/memory.py +0 -24
  222. package/server/contexts/inventory/infrastructure/repository.py +0 -8
  223. package/server/contexts/orders/__init__.py +0 -1
  224. package/server/contexts/orders/application/__init__.py +0 -19
  225. package/server/contexts/orders/application/services.py +0 -127
  226. package/server/contexts/orders/contracts/__init__.py +0 -3
  227. package/server/contexts/orders/contracts/http/__init__.py +0 -3
  228. package/server/contexts/orders/contracts/http/router.py +0 -82
  229. package/server/contexts/orders/domain/__init__.py +0 -29
  230. package/server/contexts/orders/domain/models.py +0 -95
  231. package/server/contexts/orders/infrastructure/__init__.py +0 -7
  232. package/server/contexts/orders/infrastructure/repository.py +0 -104
  233. package/server/contexts/shipping/__init__.py +0 -1
  234. package/server/contexts/shipping/application/__init__.py +0 -13
  235. package/server/contexts/shipping/application/services.py +0 -92
  236. package/server/contexts/shipping/contracts/__init__.py +0 -3
  237. package/server/contexts/shipping/contracts/http/__init__.py +0 -3
  238. package/server/contexts/shipping/contracts/http/router.py +0 -40
  239. package/server/contexts/shipping/domain/__init__.py +0 -19
  240. package/server/contexts/shipping/domain/models.py +0 -48
  241. package/server/contexts/shipping/infrastructure/__init__.py +0 -9
  242. package/server/contexts/shipping/infrastructure/repository.py +0 -50
  243. package/server/contexts/support/__init__.py +0 -1
  244. package/server/contexts/support/application/__init__.py +0 -13
  245. package/server/contexts/support/application/services.py +0 -29
  246. package/server/contexts/support/contracts/__init__.py +0 -3
  247. package/server/contexts/support/contracts/http/__init__.py +0 -3
  248. package/server/contexts/support/contracts/http/router.py +0 -40
  249. package/server/contexts/support/domain/__init__.py +0 -13
  250. package/server/contexts/support/domain/models.py +0 -27
  251. package/server/contexts/support/infrastructure/__init__.py +0 -11
  252. package/server/contexts/support/infrastructure/repository.py +0 -70
  253. package/server/contexts/user/__init__.py +0 -1
  254. package/server/contexts/user/application/__init__.py +0 -3
  255. package/server/contexts/user/application/ports.py +0 -11
  256. package/server/contexts/user/application/services.py +0 -44
  257. package/server/contexts/user/contracts/__init__.py +0 -3
  258. package/server/contexts/user/contracts/http/__init__.py +0 -3
  259. package/server/contexts/user/contracts/http/router.py +0 -26
  260. package/server/contexts/user/domain/__init__.py +0 -3
  261. package/server/contexts/user/domain/models.py +0 -22
  262. package/server/contexts/user/infrastructure/__init__.py +0 -3
  263. package/server/contexts/user/infrastructure/adapters/memory.py +0 -27
  264. package/server/contexts/user/infrastructure/adapters/mongodb.py +0 -41
  265. package/server/contexts/user/infrastructure/adapters/sqlalchemy.py +0 -94
  266. package/server/contexts/user/infrastructure/factory.py +0 -28
  267. package/server/data/README.md +0 -24
  268. package/server/data/bootstrap/alerts.json +0 -38
  269. package/server/data/bootstrap/auth_accounts.json +0 -18
  270. package/server/data/bootstrap/catalog_products.json +0 -179
  271. package/server/data/bootstrap/fulfillment_events.json +0 -5
  272. package/server/data/bootstrap/fulfillment_notes.json +0 -5
  273. package/server/data/bootstrap/fulfillment_tasks.json +0 -50
  274. package/server/data/bootstrap/inventory_levels.json +0 -80
  275. package/server/data/bootstrap/orders.json +0 -62
  276. package/server/data/bootstrap/shipping_shipments.json +0 -50
  277. package/server/data/bootstrap/support_faqs.json +0 -26
  278. package/server/data/bootstrap/users.json +0 -20
  279. package/server/data/bootstrap_loader.py +0 -15
  280. package/server/docker-entrypoint.sh +0 -56
  281. package/server/main.py +0 -3
  282. package/server/pyproject.toml +0 -36
  283. package/server/shared/__init__.py +0 -1
  284. package/server/shared/application/__init__.py +0 -3
  285. package/server/shared/application/health.py +0 -2
  286. package/server/shared/infrastructure/__init__.py +0 -10
  287. package/server/shared/infrastructure/runtime.py +0 -6
  288. package/server/shared/infrastructure/security.py +0 -33
  289. package/server/tests/e2e/test_domain_feature_flows.py +0 -483
  290. package/server/tests/test_health.py +0 -49
  291. package/server/uv.lock +0 -1169
@@ -1,126 +0,0 @@
1
- import { useEffect, useState } from "react";
2
-
3
- import {
4
- fetchCatalogProducts,
5
- type CatalogProductSummary,
6
- } from "@/api/catalog";
7
- import { useAuth } from "@/auth/AuthProvider";
8
-
9
- function productStateClassName(state: string) {
10
- if (state === "active") {
11
- return "bg-[var(--landing-accent-soft)] text-[var(--landing-accent)]";
12
- }
13
- if (state === "draft") {
14
- return "bg-[#fff2e4] text-[#b46c35]";
15
- }
16
-
17
- return "bg-[#efe4d7] text-[#7f5b39]";
18
- }
19
-
20
- export function LandingWorkspacePage() {
21
- const { token, user } = useAuth();
22
- const [products, setProducts] = useState<CatalogProductSummary[]>([]);
23
- const [loading, setLoading] = useState(true);
24
- const [error, setError] = useState<string | null>(null);
25
-
26
- useEffect(() => {
27
- let cancelled = false;
28
-
29
- setLoading(true);
30
- setError(null);
31
-
32
- fetchCatalogProducts(token?.access_token)
33
- .then((response) => {
34
- if (!cancelled) {
35
- setProducts(response);
36
- }
37
- })
38
- .catch((nextError: Error) => {
39
- if (!cancelled) {
40
- setError(nextError.message);
41
- setProducts([]);
42
- }
43
- })
44
- .finally(() => {
45
- if (!cancelled) {
46
- setLoading(false);
47
- }
48
- });
49
-
50
- return () => {
51
- cancelled = true;
52
- };
53
- }, [token?.access_token]);
54
-
55
- const highlightedProduct = products[0];
56
-
57
- return (
58
- <section className="mx-auto max-w-6xl px-6 py-10">
59
- <div className="grid gap-4 lg:grid-cols-[1.2fr_0.8fr]">
60
- <div className="rounded-[32px] border border-[#eadbcb] bg-white p-8 shadow-[0_20px_50px_rgba(123,78,42,0.08)]">
61
- <p className="text-sm font-semibold uppercase tracking-[0.18em] text-[var(--landing-accent)]">Protected workspace</p>
62
- <h1 className="mt-4 text-3xl font-black tracking-[-0.04em] text-[#2c261f]">인증된 사용자 전용 셸</h1>
63
- <p className="mt-4 max-w-2xl text-base leading-8 text-[var(--landing-muted)]">
64
- 이 화면은 저장된 토큰으로 `auth/me` 검증이 끝난 뒤에만 열립니다. 랜딩 템플릿에서도 보호 라우트와 간단한 멤버 셸을 바로 사용할 수 있습니다.
65
- </p>
66
- <div className="mt-8 rounded-[24px] bg-[#fff7f0] p-6">
67
- <div className="flex items-center justify-between gap-4">
68
- <div>
69
- <p className="text-sm text-[var(--landing-muted)]">Catalog sync</p>
70
- <p className="mt-2 text-2xl font-black text-[#2c261f]">{loading ? "..." : `${products.length} products`}</p>
71
- </div>
72
- {highlightedProduct ? (
73
- <span className={`rounded-full px-3 py-1 text-xs font-semibold uppercase ${productStateClassName(highlightedProduct.status)}`}>
74
- {highlightedProduct.status}
75
- </span>
76
- ) : null}
77
- </div>
78
- {error ? <p className="mt-4 text-sm font-semibold text-[#b85b2a]">{error}</p> : null}
79
- {!error ? <p className="mt-4 text-sm leading-7 text-[var(--landing-muted)]">{loading ? "Loading product catalog..." : highlightedProduct?.name ?? "No catalog products available."}</p> : null}
80
- </div>
81
- </div>
82
- <div className="rounded-[32px] bg-[#2c261f] p-8 text-white">
83
- <p className="text-sm text-white/65">Current member</p>
84
- <p className="mt-4 text-2xl font-black">{user?.name}</p>
85
- <dl className="mt-6 space-y-4 text-sm">
86
- <div>
87
- <dt className="text-white/55">Email</dt>
88
- <dd className="mt-1 font-semibold">{user?.email}</dd>
89
- </div>
90
- <div>
91
- <dt className="text-white/55">Role</dt>
92
- <dd className="mt-1 font-semibold">{user?.role}</dd>
93
- </div>
94
- <div>
95
- <dt className="text-white/55">Status</dt>
96
- <dd className="mt-1 font-semibold">{user?.status}</dd>
97
- </div>
98
- </dl>
99
- </div>
100
- </div>
101
-
102
- <div className="mt-6 grid gap-4 md:grid-cols-3">
103
- {loading ? (
104
- <div className="rounded-[28px] border border-[#eadbcb] bg-white p-6 md:col-span-3">
105
- <p className="text-sm text-[var(--landing-muted)]">Loading live workspace products...</p>
106
- </div>
107
- ) : null}
108
- {!loading && !error && !products.length ? (
109
- <div className="rounded-[28px] border border-[#eadbcb] bg-white p-6 md:col-span-3">
110
- <p className="text-sm text-[var(--landing-muted)]">There are no products to display in the workspace.</p>
111
- </div>
112
- ) : null}
113
- {products.map((product) => (
114
- <div key={product.id} className="rounded-[28px] border border-[#eadbcb] bg-white p-6 shadow-[0_16px_42px_rgba(123,78,42,0.06)]">
115
- <div className="flex items-center justify-between gap-3">
116
- <p className="text-sm text-[var(--landing-muted)]">{product.id}</p>
117
- <span className={`rounded-full px-3 py-1 text-xs font-semibold uppercase ${productStateClassName(product.status)}`}>{product.status}</span>
118
- </div>
119
- <p className="mt-4 text-xl font-bold text-[#2c261f]">{product.name}</p>
120
- <p className="mt-2 text-sm text-[var(--landing-muted)]">{product.brand}</p>
121
- </div>
122
- ))}
123
- </div>
124
- </section>
125
- );
126
- }
@@ -1,17 +0,0 @@
1
- @tailwind base;
2
- @tailwind components;
3
- @tailwind utilities;
4
-
5
- :root {
6
- color-scheme: light;
7
- font-family: "SUIT", "Pretendard", "Noto Sans KR", sans-serif;
8
- }
9
-
10
- body {
11
- margin: 0;
12
- background: var(--landing-bg, #f6f1e9);
13
- }
14
-
15
- * {
16
- box-sizing: border-box;
17
- }
@@ -1,16 +0,0 @@
1
- import type { CSSProperties } from "react";
2
-
3
- import type { LandingTheme } from "./theme";
4
-
5
- export function landingThemeVars(theme: LandingTheme): CSSProperties {
6
- return {
7
- "--landing-bg": theme.bg,
8
- "--landing-text": theme.text,
9
- "--landing-muted": theme.muted,
10
- "--landing-accent": theme.accent,
11
- "--landing-accent-soft": theme.accentSoft,
12
- "--landing-card-radius": theme.cardRadius,
13
- "--landing-section-gap": theme.sectionGap,
14
- "--landing-hero-pad-y": theme.heroPadY,
15
- } as CSSProperties;
16
- }
@@ -1,21 +0,0 @@
1
- export type LandingTheme = {
2
- bg: string;
3
- text: string;
4
- muted: string;
5
- accent: string;
6
- accentSoft: string;
7
- cardRadius: string;
8
- sectionGap: string;
9
- heroPadY: string;
10
- };
11
-
12
- export const landingTheme: LandingTheme = {
13
- bg: "#f6f1e9",
14
- text: "#2e261e",
15
- muted: "#726454",
16
- accent: "#d36e3f",
17
- accentSoft: "#f3d7c8",
18
- cardRadius: "24px",
19
- sectionGap: "24px",
20
- heroPadY: "88px",
21
- };
@@ -1 +0,0 @@
1
- /// <reference types="vite/client" />
@@ -1,8 +0,0 @@
1
- /** @type {import('tailwindcss').Config} */
2
- export default {
3
- content: ["./index.html", "./src/**/*.{ts,tsx}"],
4
- theme: {
5
- extend: {},
6
- },
7
- plugins: [],
8
- };
@@ -1,25 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "useDefineForClassFields": true,
5
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
- "allowJs": false,
7
- "skipLibCheck": true,
8
- "esModuleInterop": true,
9
- "allowSyntheticDefaultImports": true,
10
- "strict": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "module": "ESNext",
13
- "moduleResolution": "Node",
14
- "resolveJsonModule": true,
15
- "isolatedModules": true,
16
- "noEmit": true,
17
- "jsx": "react-jsx",
18
- "baseUrl": ".",
19
- "paths": {
20
- "@/*": ["src/*"]
21
- }
22
- },
23
- "include": ["src"],
24
- "references": []
25
- }
@@ -1,12 +0,0 @@
1
- import { defineConfig } from "vite";
2
- import react from "@vitejs/plugin-react";
3
- import { fileURLToPath, URL } from "node:url";
4
-
5
- export default defineConfig({
6
- plugins: [react()],
7
- resolve: {
8
- alias: {
9
- "@": fileURLToPath(new URL("./src", import.meta.url)),
10
- },
11
- },
12
- });
@@ -1,2 +0,0 @@
1
- node_modules
2
- dist
@@ -1 +0,0 @@
1
- VITE_API_BASE_URL=http://127.0.0.1:8000/api/v1
@@ -1,16 +0,0 @@
1
- FROM node:20-slim
2
-
3
- WORKDIR /app
4
-
5
- COPY pnpm-lock.yaml pnpm-workspace.yaml ./
6
- COPY client/mobile/package.json ./client/mobile/package.json
7
-
8
- RUN npm install -g pnpm@10.32.0 && pnpm install --filter @do4ai/client-mobile-template...
9
-
10
- COPY . .
11
-
12
- WORKDIR /app/client/mobile
13
-
14
- EXPOSE 3002
15
-
16
- CMD ["pnpm", "dev", "--host", "0.0.0.0", "--port", "3002"]
@@ -1,18 +0,0 @@
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/mobile/package.json ./client/mobile/package.json
9
-
10
- RUN pnpm install --frozen-lockfile --filter @do4ai/client-mobile-template...
11
-
12
- COPY client/mobile ./client/mobile
13
-
14
- WORKDIR /app/client/mobile
15
-
16
- EXPOSE 3002
17
-
18
- CMD ["sh", "-lc", "pnpm exec vite --host 0.0.0.0 --port ${PORT:-3002}"]
@@ -1,19 +0,0 @@
1
- # mobile
2
-
3
- 다국어 안내, 현장 운영, 파트너 협업 같은 `IN` 표면을 위한 프론트엔드 보일러플레이트다.
4
-
5
- 포함 패턴:
6
-
7
- - 현장 운영형 header + workspace shell
8
- - KPI summary + action board
9
- - 서비스 현황 list/detail surface
10
- - CSS variable 기반 theme surface
11
-
12
- 시작:
13
-
14
- ```bash
15
- npm install
16
- npm run dev
17
- ```
18
-
19
- 기본 DEV 포트는 `3002`다.
@@ -1,12 +0,0 @@
1
- <!doctype html>
2
- <html lang="ko">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>client-mobile template</title>
7
- </head>
8
- <body>
9
- <div id="root"></div>
10
- <script type="module" src="/src/main.tsx"></script>
11
- </body>
12
- </html>
@@ -1,42 +0,0 @@
1
- {
2
- "name": "@do4ai/client-mobile-template",
3
- "private": true,
4
- "version": "0.1.0",
5
- "type": "module",
6
- "packageManager": "pnpm@10.32.0",
7
- "scripts": {
8
- "dev": "vite --host 0.0.0.0 --port 3002",
9
- "build": "tsc -b && vite build",
10
- "preview": "vite preview --host 0.0.0.0 --port 4302",
11
- "ui:parity:init": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/init_frontend_parity.sh ../.. mobile",
12
- "ui:parity:bootstrap": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/bootstrap_frontend_parity.sh ../.. mobile",
13
- "ui:parity:scaffold": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/run_frontend_target.sh scaffold ../.. mobile",
14
- "ui:parity:materialize-references": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/run_frontend_target.sh materialize_references ../.. mobile",
15
- "ui:parity:route-gap": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/run_frontend_target.sh route_gap ../.. mobile",
16
- "ui:parity:proof": "bash ../../sdd/99_toolchain/01_automation/agentic-dev/run_frontend_target.sh proof ../.. mobile",
17
- "ui:parity": "npm run ui:parity:proof"
18
- },
19
- "dependencies": {
20
- "class-variance-authority": "^0.7.1",
21
- "clsx": "^2.1.1",
22
- "lucide-react": "^0.576.0",
23
- "react": "^18.3.1",
24
- "react-dom": "^18.3.1",
25
- "react-router-dom": "^6.30.1",
26
- "tailwind-merge": "^3.5.0"
27
- },
28
- "devDependencies": {
29
- "@playwright/test": "^1.58.2",
30
- "@types/react": "^18.3.18",
31
- "@types/react-dom": "^18.3.5",
32
- "@vitejs/plugin-react": "^4.7.0",
33
- "autoprefixer": "^10.4.21",
34
- "pixelmatch": "^7.1.0",
35
- "pngjs": "^7.0.0",
36
- "postcss": "^8.5.3",
37
- "tailwindcss": "^3.4.17",
38
- "typescript": "^5.8.3",
39
- "vite": "^5.4.19",
40
- "yaml": "^2.8.1"
41
- }
42
- }
@@ -1,6 +0,0 @@
1
- export default {
2
- plugins: {
3
- tailwindcss: {},
4
- autoprefixer: {},
5
- },
6
- };
@@ -1,67 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
-
5
- const scriptDir = path.dirname(fileURLToPath(import.meta.url));
6
- const screens = JSON.parse(
7
- fs.readFileSync(path.resolve(scriptDir, "../src/lib/specScreens.json"), "utf8"),
8
- );
9
- const routes = JSON.parse(
10
- fs.readFileSync(path.resolve(scriptDir, "../src/lib/specRouteCatalog.json"), "utf8"),
11
- );
12
-
13
- const routeMap = new Map(routes.map((entry) => [entry.id, entry.route]));
14
-
15
- export default {
16
- service: "templates-mobile",
17
- targetBaseUrl: "http://127.0.0.1:4302",
18
- viewport: {
19
- width: 1440,
20
- height: 1024,
21
- },
22
- screens: screens.map((screen) => ({
23
- id: screen.id,
24
- title: screen.title,
25
- route: routeMap.get(screen.id) ?? "/",
26
- referenceImage: `sdd/03_verify/10_test/ui_parity/reference/${screen.id}.png`,
27
- readySelector: "body",
28
- readyTimeoutMs: 10000,
29
- tags: ["template", "mobile"],
30
- })),
31
- async preparePage(page, { route }) {
32
- await page.route("**/auth/me", async (routeRequest) => {
33
- await routeRequest.fulfill({
34
- status: 200,
35
- contentType: "application/json",
36
- body: JSON.stringify({
37
- id: "tmpl-mobile",
38
- name: "Template Mobile Operator",
39
- email: "operator@example.com",
40
- role: "operator",
41
- status: "active",
42
- }),
43
- });
44
- });
45
- await page.addInitScript(() => {
46
- window.localStorage.setItem(
47
- "mobile.auth.token",
48
- JSON.stringify({
49
- access_token: "template-access-token",
50
- token_type: "bearer",
51
- user_id: "tmpl-mobile",
52
- }),
53
- );
54
- });
55
- if (route === "/login") {
56
- await page.addInitScript(() => {
57
- window.localStorage.removeItem("mobile.auth.token");
58
- });
59
- }
60
- },
61
- async waitForReady(page) {
62
- await page.waitForLoadState("networkidle");
63
- },
64
- async resolveMaskRects() {
65
- return [];
66
- },
67
- };
@@ -1 +0,0 @@
1
- export { App } from "./app/App";
@@ -1,62 +0,0 @@
1
- const API_BASE_URL =
2
- (import.meta.env.VITE_API_BASE_URL as string | undefined)?.replace(/\/$/, "") ??
3
- "";
4
-
5
- interface RequestOptions {
6
- accessToken?: string;
7
- }
8
-
9
- interface WriteOptions extends RequestOptions {
10
- body?: unknown;
11
- }
12
-
13
- async function readJson<T>(response: Response): Promise<T> {
14
- if (!response.ok) {
15
- let message = "Request failed";
16
- try {
17
- const data = (await response.json()) as { detail?: string };
18
- if (typeof data.detail === "string" && data.detail.length > 0) {
19
- message = data.detail;
20
- }
21
- } catch {
22
- message = response.statusText || message;
23
- }
24
- throw new Error(message);
25
- }
26
-
27
- return (await response.json()) as T;
28
- }
29
-
30
- export async function apiGet<T>(
31
- path: string,
32
- options?: RequestOptions,
33
- ): Promise<T> {
34
- const response = await fetch(`${API_BASE_URL}${path}`, {
35
- headers: options?.accessToken
36
- ? { Authorization: `Bearer ${options.accessToken}` }
37
- : undefined,
38
- });
39
-
40
- return readJson<T>(response);
41
- }
42
-
43
- export async function apiPatch<T>(
44
- path: string,
45
- options?: WriteOptions,
46
- ): Promise<T> {
47
- const headers: Record<string, string> = {
48
- "Content-Type": "application/json",
49
- };
50
-
51
- if (options?.accessToken) {
52
- headers.Authorization = `Bearer ${options.accessToken}`;
53
- }
54
-
55
- const response = await fetch(`${API_BASE_URL}${path}`, {
56
- method: "PATCH",
57
- headers,
58
- body: JSON.stringify(options?.body ?? {}),
59
- });
60
-
61
- return readJson<T>(response);
62
- }
@@ -1,55 +0,0 @@
1
- import { apiGet } from "@/api/client";
2
-
3
- export interface FulfillmentStat {
4
- label: string;
5
- value: string;
6
- tone?: string | null;
7
- }
8
-
9
- export interface FulfillmentTimelineItem {
10
- time: string;
11
- title: string;
12
- tone: string;
13
- }
14
-
15
- export interface FulfillmentStageLoad {
16
- label: string;
17
- value: string;
18
- }
19
-
20
- export interface FulfillmentOverviewResponse {
21
- throughput_total: string;
22
- stats: FulfillmentStat[];
23
- timeline: FulfillmentTimelineItem[];
24
- stage_load: FulfillmentStageLoad[];
25
- }
26
-
27
- export interface FulfillmentTask {
28
- id: string;
29
- order_id: string;
30
- title: string;
31
- assignee: string;
32
- stage: string;
33
- status: string;
34
- priority: string;
35
- sla: string;
36
- }
37
-
38
- export interface FulfillmentNote {
39
- id: string;
40
- note: string;
41
- emphasis: string;
42
- }
43
-
44
- export interface FulfillmentBoardResponse {
45
- tasks: FulfillmentTask[];
46
- notes: FulfillmentNote[];
47
- }
48
-
49
- export function fetchFulfillmentOverview(accessToken: string) {
50
- return apiGet<FulfillmentOverviewResponse>("/fulfillment/overview", { accessToken });
51
- }
52
-
53
- export function fetchFulfillmentBoard(accessToken: string) {
54
- return apiGet<FulfillmentBoardResponse>("/fulfillment/board", { accessToken });
55
- }
@@ -1,56 +0,0 @@
1
- import { apiGet, apiPatch } from "@/api/client";
2
-
3
- export interface ShippingStat {
4
- label: string;
5
- value: string;
6
- tone?: string | null;
7
- }
8
-
9
- export interface ShippingCarrierLoad {
10
- label: string;
11
- value: string;
12
- }
13
-
14
- export interface ShippingOverviewResponse {
15
- stats: ShippingStat[];
16
- carriers: ShippingCarrierLoad[];
17
- highlighted_route: string;
18
- }
19
-
20
- export interface ShipmentSummary {
21
- shipment_id: string;
22
- order_id: string;
23
- carrier: string;
24
- destination: string;
25
- tracking_number: string;
26
- status: string;
27
- eta: string;
28
- last_event: string;
29
- }
30
-
31
- export interface ShipmentStatusTransition {
32
- shipment_id: string;
33
- previous_status: string;
34
- status: string;
35
- previous_last_event: string;
36
- last_event: string;
37
- }
38
-
39
- export function fetchShippingOverview(accessToken: string) {
40
- return apiGet<ShippingOverviewResponse>("/shipping/overview", { accessToken });
41
- }
42
-
43
- export function fetchShipments(accessToken: string) {
44
- return apiGet<ShipmentSummary[]>("/shipping/shipments", { accessToken });
45
- }
46
-
47
- export function updateShipmentStatus(
48
- shipmentId: string,
49
- accessToken: string,
50
- body: { status: string; last_event: string; eta?: string },
51
- ) {
52
- return apiPatch<ShipmentStatusTransition>(
53
- `/shipping/shipments/${shipmentId}/status`,
54
- { accessToken, body },
55
- );
56
- }
@@ -1,23 +0,0 @@
1
- import { Route, Routes } from "react-router-dom";
2
-
3
- import { ProtectedRoute } from "@/auth/ProtectedRoute";
4
- import { InShell } from "@/components/InShell";
5
- import { DashboardPage } from "@/pages/DashboardPage";
6
- import { FulfillmentPage } from "@/pages/FulfillmentPage";
7
- import { LoginPage } from "@/pages/LoginPage";
8
- import { ShippingPage } from "@/pages/ShippingPage";
9
-
10
- export function App() {
11
- return (
12
- <Routes>
13
- <Route path="/login" element={<LoginPage />} />
14
- <Route element={<ProtectedRoute />}>
15
- <Route element={<InShell />}>
16
- <Route path="/" element={<DashboardPage />} />
17
- <Route path="/fulfillment" element={<FulfillmentPage />} />
18
- <Route path="/shipping" element={<ShippingPage />} />
19
- </Route>
20
- </Route>
21
- </Routes>
22
- );
23
- }