vooster__guideline.mdc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. ---
  2. description:
  3. globs:
  4. alwaysApply: true
  5. ---
  6. # Code Guidelines for Influencer–Vendor Automation Platform
  7. ## 1. Project Overview
  8. A unified web platform to automate ordering, shipping, settlement, and notifications between influencers and vendors.
  9. Key architectural decisions:
  10. - Frontend: Vue 3 + Nuxt 3 (SSR/SSG), Composition API, TypeScript, Pinia, Vuetify, Axios
  11. - BFF: Node.js + Express (ES Modules), Socket.IO for real-time
  12. - Backend API: CodeIgniter 4 RESTful controllers, MySQL (RDS), Redis cache
  13. - Deployment: Docker → Kubernetes, CI/CD via GitHub Actions
  14. - Integrations: Google Cloud Vision OCR, Courier & ERP REST APIs, JWT/OAuth2 authentication
  15. ---
  16. ## 2. Core Principles
  17. 1. Single Responsibility: each function/module addresses one concern; max 200 lines.
  18. 2. Strong Typing: avoid `any`; define interfaces for props, DTOs, API responses.
  19. 3. Consistent Error Handling: centralize and standardize error responses and logs.
  20. 4. DRY & Reusable: extract shared logic into composables, services, or utilities.
  21. 5. Domain-Driven Modules: group files by business domain (order, shipping, finance).
  22. ---
  23. ## 3. Language-Specific Guidelines
  24. ### 3.1 Vue 3 + Nuxt 3 + TypeScript
  25. - File Organization:
  26. - `/pages` → route pages
  27. - `/components/{domain}` → feature components
  28. - `/composables` → reusable logic hooks (prefixed `useXxx`)
  29. - `/stores/{domain}` → Pinia modules (one per domain)
  30. - `/plugins`, `/middleware`, `/assets`, `/layouts`
  31. - Imports & Aliases:
  32. - Use Nuxt aliases: `import X from '~/components/order/OrderList.vue'`
  33. - Group imports: external packages → aliased aliases → relative (sorted alphabetically)
  34. - Error Handling:
  35. - Global error plugin `~/plugins/error.ts` to catch and display Axios errors
  36. - In composable:
  37. ```ts
  38. export async function useFetchOrders() {
  39. try {
  40. const { data } = await $axios.get<Order[]>('/api/orders')
  41. return data
  42. } catch (error: unknown) {
  43. throw new ApiError(error)
  44. }
  45. }
  46. ```
  47. ### 3.2 Node.js + Express (BFF)
  48. - Folder Structure:
  49. ```
  50. /src
  51. /controllers
  52. /services
  53. /routes
  54. /middlewares
  55. /utils
  56. app.js
  57. ```
  58. - Dependency Management:
  59. - Use ES Modules (`"type": "module"`) or TypeScript.
  60. - Version-lock in `package.json`; run `npm audit` in CI.
  61. - Error Handling:
  62. - Create `HttpError` class in `/utils/HttpError.js`
  63. - Middleware `errorHandler.js` at the end:
  64. ```js
  65. app.use((err, req, res, next) => {
  66. logger.error(err)
  67. res.status(err.statusCode || 500).json({
  68. success: false,
  69. message: err.message || 'Internal Server Error'
  70. })
  71. })
  72. ```
  73. ### 3.3 CodeIgniter 4 (REST API)
  74. - Controllers: one per resource, extend `ResourceController`
  75. - Models: use Entities and Query Builder; keep business logic in Services
  76. - Validation & Responses:
  77. ```php
  78. public function create()
  79. {
  80. $rules = ['order_id' => 'required|integer', /* ... */];
  81. if (! $this->validate($rules)) {
  82. return $this->fail($this->validator->getErrors());
  83. }
  84. $entity = new OrderEntity($this->request->getPost());
  85. $this->orderService->save($entity);
  86. return $this->respondCreated($entity);
  87. }
  88. ```
  89. - Error Handling: use `HTTPException` for 404/403, global logging in `app/Filters`.
  90. ---
  91. ## 4. Code Style Rules
  92. ### 4.1 MUST Follow
  93. - **Use Strict Typescript**
  94. Rationale: catch errors at compile time.
  95. ```jsonc
  96. // tsconfig.json
  97. {
  98. "compilerOptions": {
  99. "strict": true,
  100. "noImplicitAny": true,
  101. "forceConsistentCasingInFileNames": true
  102. }
  103. }
  104. ```
  105. - **One Component per File**
  106. Rationale: clarity, reusability, smaller diffs.
  107. - **Composition API & `<script setup>`**
  108. Rationale: simpler syntax and tree-shaking.
  109. ```vue
  110. <script setup lang="ts">
  111. import { ref } from 'vue'
  112. const count = ref(0)
  113. function increment() { count.value++ }
  114. </script>
  115. ```
  116. - **Pinia Stores for State**
  117. Rationale: predictable global state with actions, getters.
  118. ```ts
  119. import { defineStore } from 'pinia'
  120. export const useOrderStore = defineStore('order', {
  121. state: () => ({ list: [] as Order[] }),
  122. actions: {
  123. async fetch() { this.list = await fetchOrders() }
  124. }
  125. })
  126. ```
  127. - **RESTful API Design**
  128. Rationale: consistency and predictability.
  129. - Use resource paths: `/vendors/{id}/orders`
  130. - HTTP verbs: GET/POST/PUT/DELETE
  131. - Standard response envelope:
  132. ```json
  133. { "success": true, "data": {...}, "error": null }
  134. ```
  135. - **Centralized Error Handler**
  136. Rationale: unified logging and client messages.
  137. ### 4.2 MUST NOT Do
  138. - **Avoid `any` or disabling lint rules**
  139. Rationale: loses type-safety.
  140. - **No Large “God” Modules**
  141. Rationale: hard to test and maintain.
  142. - **No Inline Styles or Scripts**
  143. Rationale: separates concerns; use Vuetify theme or SCSS.
  144. - **No Nested Callbacks (Callback Hell)**
  145. Rationale: use async/await or Promises.
  146. - **No Direct DOM Manipulation**
  147. Rationale: Vue manages DOM; use refs or directives.
  148. ---
  149. ## 5. Architecture Patterns
  150. ### 5.1 Component & Module Structure
  151. - Domain-Driven Folders:
  152. ```
  153. /components/order
  154. /components/shipping
  155. /composables/order
  156. /stores/order
  157. /services/api/order.ts
  158. ```
  159. - Layers in BFF:
  160. - **Routes** → **Controllers** → **Services** → **Data Access**
  161. ### 5.2 Data Flow
  162. - **Frontend**: Props ↓, Events ↑, Store (Pinia) for shared state, Composables for side-effects.
  163. - **API Calls**: Axios interceptors attach JWT, handle 401 globally, retry logic for idempotent GETs.
  164. - **Real-time**: Socket.IO client in plugin; update Pinia store on events.
  165. ### 5.3 State Management
  166. - Local state in component for UI-only values (`ref`, `reactive`).
  167. - Global state in Pinia: one store per domain; expose typed actions/getters.
  168. - Keep store actions async, commit minimal state changes.
  169. ### 5.4 API Design Standards
  170. - Base URL per domain: `/api/v1/orders`, `/api/v1/vendors`
  171. - Pagination: standard query `?page=1&limit=20`, return `{ items, total, page, limit }`.
  172. - Filtering & Sorting: query params `?status=shipped&sort=-date`.
  173. - Consistent Error Payload:
  174. ```json
  175. {
  176. "success": false,
  177. "error": {
  178. "code": "VALIDATION_FAILED",
  179. "message": "Invalid field: quantity"
  180. }
  181. }
  182. ```
  183. ---
  184. ## 6. Example Code Snippets
  185. ### 6.1 Vue Composition & API Call
  186. ```ts
  187. // MUST: composable with typed response and error handling
  188. import { ref } from 'vue'
  189. import { Order } from '~/types'
  190. import { useApi } from '~/composables/useApi'
  191. export function useOrders() {
  192. const list = ref<Order[]>([])
  193. const error = ref<string | null>(null)
  194. async function fetchOrders() {
  195. try {
  196. const res = await useApi().get<Order[]>('/orders')
  197. list.value = res.data
  198. } catch (e) {
  199. error.value = e.message
  200. }
  201. }
  202. return { list, error, fetchOrders }
  203. }
  204. ```
  205. ```ts
  206. // MUST NOT: direct Axios calls in component, untyped any
  207. setup() {
  208. axios.get('/orders').then(res => {
  209. this.orders = res.data
  210. })
  211. }
  212. ```
  213. ### 6.2 Node.js Express Route & Error
  214. ```js
  215. // MUST: clean controller and error propagation
  216. // src/routes/order.js
  217. import { Router } from 'express'
  218. import { listOrders } from '../controllers/order.js'
  219. const router = Router()
  220. router.get('/', listOrders)
  221. export default router
  222. // src/controllers/order.js
  223. export async function listOrders(req, res, next) {
  224. try {
  225. const orders = await OrderService.fetchAll()
  226. res.json({ success: true, data: orders })
  227. } catch (err) {
  228. next(new HttpError(500, 'Failed to fetch orders'))
  229. }
  230. }
  231. ```
  232. ```js
  233. // MUST NOT: catch without forwarding or unstructured response
  234. app.get('/orders', async (req, res) => {
  235. try {
  236. const orders = await OrderService.fetchAll()
  237. res.send(orders)
  238. } catch (err) {
  239. res.status(500).send('Error')
  240. }
  241. })
  242. ```
  243. ### 6.3 CodeIgniter4 Controller
  244. ```php
  245. // MUST: validate, use entity, consistent response
  246. class OrderController extends ResourceController
  247. {
  248. public function create()
  249. {
  250. $rules = ['vendor_id'=>'required|integer', 'items'=>'required|array'];
  251. if (! $this->validate($rules)) {
  252. return $this->failValidationErrors($this->validator->getErrors());
  253. }
  254. $order = new OrderEntity($this->request->getPost());
  255. $this->orderService->create($order);
  256. return $this->respondCreated(['order' => $order]);
  257. }
  258. }
  259. ```
  260. ```php
  261. // MUST NOT: raw SQL in controller, no validation
  262. class OrderController extends BaseController
  263. {
  264. public function create()
  265. {
  266. $db->query("INSERT INTO orders ..."); // anti-pattern
  267. }
  268. }
  269. ```
  270. ---
  271. End of Guidelines.
  272. Follow these rules as the single source of truth for code quality, maintainability, and consistency.