diff --git a/002_source/cms/.eslintrc.js b/002_source/cms/.eslintrc.js index 2b244e1..9df006e 100644 --- a/002_source/cms/.eslintrc.js +++ b/002_source/cms/.eslintrc.js @@ -1,7 +1,6 @@ const { resolve } = require('node:path'); const project = resolve(__dirname, 'tsconfig.json'); - module.exports = { root: true, extends: [ @@ -84,4 +83,13 @@ module.exports = { 'react/jsx-sort-props': 'off', }, ignorePatterns: ['**/*del', '**/*bak', '**/*copy.*', '**/*copy*.*'], + overrides: [ + { + // override to ignore no-def for `describe`, `it`, and `expect` + files: ['*.test.ts', '*.test.tsx'], + rules: { + 'no-undef': 'off', + }, + }, + ], }; diff --git a/002_source/cms/_AI_WORKSPACE/code/001_INIT.md b/002_source/cms/_AI_WORKSPACE/code/001_INIT.md new file mode 100644 index 0000000..d794e3d --- /dev/null +++ b/002_source/cms/_AI_WORKSPACE/code/001_INIT.md @@ -0,0 +1,44 @@ +# AI GUIDELINE + +## getting started + +Imagine there is a: + +1. developer (provide the modification) +2. QA engineer (provide the feedback, and testing) +3. software engineer +4. technical writer + +they will: + +- conclude and integrate the ideas from developer and QA engineer +- make decision to modify the code accordingly. + +## project background and initial setup + +- No need to reply me what you are going on and your digest in this phase. + Just reply me "OK" when done + +- base_dir=`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project` + +- `schema.dbml` + + - read `/001_documentation/Requirements/REQ0006/schema.dbml` + this is file in `dbml` format stating the main database structure + +- `schema.json` + + - read `/002_source/cms/src/db/schema.json` + this is the file of current pocketbase schema + +- read `/002_source/cms/src/constants.ts` + this is the content of `@/constants` + +- look into the md files in folder `/002_source/cms/_AI_WORKSPACE/001_guideline` + +- directory may contain `repomix-output.xml` file, that is a simple summary of all files inside the directory + +- if the directory user provided contins `_GUIDELINES.md`, please read the file + +- read the files, remember and link up the ideas in file stated above, + i will tell them the task afterwards diff --git a/002_source/cms/_AI_WORKSPACE/code/002_nextjs.mdc b/002_source/cms/_AI_WORKSPACE/code/002_nextjs.mdc new file mode 100644 index 0000000..ae7f4e0 --- /dev/null +++ b/002_source/cms/_AI_WORKSPACE/code/002_nextjs.mdc @@ -0,0 +1,52 @@ +--- +description: Next.js with TypeScript and Tailwind UI best practices +globs: **/*.tsx, **/*.ts, src/**/*.ts, src/**/*.tsx +--- + +# Next.js Best Practices + +## Project Structure +- Use the App Router directory structure +- Place components in `app` directory for route-specific components +- Place shared components in `components` directory +- Place utilities and helpers in `lib` directory +- Use lowercase with dashes for directories (e.g., `components/auth-wizard`) + +## Components +- Use Server Components by default +- Mark client components explicitly with 'use client' +- Wrap client components in Suspense with fallback +- Use dynamic loading for non-critical components +- Implement proper error boundaries +- Place static content and interfaces at file end + +## Performance +- Optimize images: Use WebP format, size data, lazy loading +- Minimize use of 'useEffect' and 'setState' +- Favor Server Components (RSC) where possible +- Use dynamic loading for non-critical components +- Implement proper caching strategies + +## Data Fetching +- Use Server Components for data fetching when possible +- Implement proper error handling for data fetching +- Use appropriate caching strategies +- Handle loading and error states appropriately + +## Routing +- Use the App Router conventions +- Implement proper loading and error states for routes +- Use dynamic routes appropriately +- Handle parallel routes when needed + +## Forms and Validation +- Use Zod for form validation +- Implement proper server-side validation +- Handle form errors appropriately +- Show loading states during form submission + +## State Management +- Minimize client-side state +- Use React Context sparingly +- Prefer server state when possible +- Implement proper loading states \ No newline at end of file diff --git a/002_source/cms/_AI_WORKSPACE/code/003_typescript.mdc b/002_source/cms/_AI_WORKSPACE/code/003_typescript.mdc new file mode 100644 index 0000000..b3919bd --- /dev/null +++ b/002_source/cms/_AI_WORKSPACE/code/003_typescript.mdc @@ -0,0 +1,57 @@ +--- +description: TypeScript coding standards and best practices for modern web development +globs: **/*.ts, **/*.tsx, **/*.d.ts +--- + +# TypeScript Best Practices + +## Type System +- Prefer interfaces over types for object definitions +- Use type for unions, intersections, and mapped types +- Avoid using `any`, prefer `unknown` for unknown types +- Use strict TypeScript configuration +- Leverage TypeScript's built-in utility types +- Use generics for reusable type patterns + +## Naming Conventions +- Use PascalCase for type names and interfaces +- Use camelCase for variables and functions +- Use UPPER_CASE for constants +- Use descriptive names with auxiliary verbs (e.g., isLoading, hasError) +- Prefix interfaces for React props with 'Props' (e.g., ButtonProps) + +## Code Organization +- Keep type definitions close to where they're used +- Export types and interfaces from dedicated type files when shared +- Use barrel exports (index.ts) for organizing exports +- Place shared types in a `types` directory +- Co-locate component props with their components + +## Functions +- Use explicit return types for public functions +- Use arrow functions for callbacks and methods +- Implement proper error handling with custom error types +- Use function overloads for complex type scenarios +- Prefer async/await over Promises + +## Best Practices +- Enable strict mode in tsconfig.json +- Use readonly for immutable properties +- Leverage discriminated unions for type safety +- Use type guards for runtime type checking +- Implement proper null checking +- Avoid type assertions unless necessary + +## Error Handling +- Create custom error types for domain-specific errors +- Use Result types for operations that can fail +- Implement proper error boundaries +- Use try-catch blocks with typed catch clauses +- Handle Promise rejections properly + +## Patterns +- Use the Builder pattern for complex object creation +- Implement the Repository pattern for data access +- Use the Factory pattern for object creation +- Leverage dependency injection +- Use the Module pattern for encapsulation \ No newline at end of file diff --git a/002_source/cms/_AI_WORKSPACE/init.md b/002_source/cms/_AI_WORKSPACE/init.md new file mode 100644 index 0000000..7ef4f78 --- /dev/null +++ b/002_source/cms/_AI_WORKSPACE/init.md @@ -0,0 +1 @@ +please read, understand and remember `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/_AI_WORKSPACE/code` diff --git a/002_source/cms/package.json b/002_source/cms/package.json index 726d197..94e2dbb 100644 --- a/002_source/cms/package.json +++ b/002_source/cms/package.json @@ -91,6 +91,7 @@ "zod": "3.22.4" }, "devDependencies": { + "@faker-js/faker": "^9.7.0", "@ianvs/prettier-plugin-sort-imports": "4.1.1", "@testing-library/jest-dom": "6.4.2", "@testing-library/react": "14.2.1", @@ -116,4 +117,4 @@ "protobufjs" ] } -} \ No newline at end of file +} diff --git a/002_source/cms/pnpm-lock.yaml b/002_source/cms/pnpm-lock.yaml index 2f7500d..4cb72ae 100644 --- a/002_source/cms/pnpm-lock.yaml +++ b/002_source/cms/pnpm-lock.yaml @@ -195,6 +195,9 @@ importers: specifier: 3.22.4 version: 3.22.4 devDependencies: + '@faker-js/faker': + specifier: ^9.7.0 + version: 9.7.0 '@ianvs/prettier-plugin-sort-imports': specifier: 4.1.1 version: 4.1.1(prettier@3.2.5) @@ -725,6 +728,10 @@ packages: resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@faker-js/faker@9.7.0': + resolution: {integrity: sha512-aozo5vqjCmDoXLNUJarFZx2IN/GgGaogY4TMJ6so/WLZOWpSV7fvj2dmrV6sEAnUm1O7aCrhTibjpzeDFgNqbg==} + engines: {node: '>=18.0.0', npm: '>=9.0.0'} + '@fastify/busboy@2.1.0': resolution: {integrity: sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==} engines: {node: '>=14'} @@ -6303,6 +6310,8 @@ snapshots: '@eslint/js@8.57.0': {} + '@faker-js/faker@9.7.0': {} + '@fastify/busboy@2.1.0': {} '@firebase/analytics-compat@0.2.7(@firebase/app-compat@0.2.27)(@firebase/app@0.9.27)': diff --git a/002_source/cms/scripts/006_test.sh b/002_source/cms/scripts/006_test.sh new file mode 100755 index 0000000..823802b --- /dev/null +++ b/002_source/cms/scripts/006_test.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -ex + +node ./scripts/update_repomix.js + +echo "done" diff --git a/002_source/cms/scripts/999_express_commit.sh b/002_source/cms/scripts/999_express_commit.sh new file mode 100755 index 0000000..c52a938 --- /dev/null +++ b/002_source/cms/scripts/999_express_commit.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -ex + +git add src +git commit -m'update,' + +echo "done" diff --git a/002_source/cms/scripts/update_repomix.js b/002_source/cms/scripts/update_repomix.js index 6d04303..16e74e5 100644 --- a/002_source/cms/scripts/update_repomix.js +++ b/002_source/cms/scripts/update_repomix.js @@ -2,16 +2,17 @@ const exec = require('child_process').exec; let directories = [ // - './src/db', - 'src/app/dashboard/lp', - 'src/app/dashboard/mf', - 'src/app/dashboard/cr', - 'src/components/dashboard/lp', - 'src/components/dashboard/mf', - 'src/components/dashboard/cr', - 'src/app/dashboard/Sample', + // './src/db', + // './src/app/dashboard/lp', + // './src/app/dashboard/mf', + // './src/app/dashboard/cr', + // './src/components/dashboard/lp', + // './src/components/dashboard/mf', + // './src/components/dashboard/cr', + // './src/app/dashboard/Sample', + './src/components/dashboard/customer', ].map((directory) => { - return `cd ${directory} && pnpx repomix`; + return `cd ${directory} && pnpx repomix -c /home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/repomix.config.json`; }); Promise.all( @@ -34,4 +35,5 @@ Promise.all( }) .catch((error) => { console.error(error); + // process.exit(1); }); diff --git a/002_source/cms/src/db/DB_AI_GUIDELINE.MD b/002_source/cms/src/db/DB_AI_GUIDELINE.MD deleted file mode 100644 index b2a12a6..0000000 --- a/002_source/cms/src/db/DB_AI_GUIDELINE.MD +++ /dev/null @@ -1,108 +0,0 @@ -# AI GUIDELINE - -## getting started - -Imagine there is a software developer and a QA engineer to solve the problems together - -They will: - -no need to reply me what you are going on and your digest in this phase. -just reply me "OK" when done - -base_dir=`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project` - -- read `/001_documentation/Requirements/REQ0006/schema.dbml` -this is file in dbml syntax state the main database - -- read `/002_source/cms/src/db/schema.json` -this is the file of live pocketbase schema output - -- read `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/constants.ts` -this is the content of `@/constants` - -- look into the md files in folder `/002_source/cms/_AI_GUIDELINE` - -- read, remember and link up the ideas in file stated above, -i will tell them the task afterwards - ---- - -The software engineer will provide solutions, -while QA engineer will feedback the opinion. - -this is now not in debug phase, -so, no need to reply me what they are going on or their insight throught the prompt. -just reply me "OK" when done - ---- - -clone `GetVisibleCount.tsx` and `GetHiddenCount.tsx` from `LessonTypes` to `LessonCategories` and update it - -please draft `GetHiddenCount.tsx` for COL_LESSON_TYPES and `status = hidden` - -well done !, please proceed to another request - -working directory: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db` - -according information from `schema.json`, get the collection of `Students` - -pleaes clone the `tsx` files from `LessonTypes` and `LessonCategories` to `Students` and update the content - -when you draft coding, review file and append with `.tsx.draft` - ---- - -- this is part of react typescript project, with pocketbase -- `schema.dbml`, describe the collections(tables) -- folder `LessonCategories`, the correct references -- folder `LessonTypes`, the correct references -- you can find the `schema.dbml` and schema information from `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/001_documentation/Requirements/REQ0006` -- do not read root directory, assume it is a fresh copy of nextjs project is ok - -## instruction - -- break the questions into smaller parts -- review file append with `.draft`, see if the content aligned with the correct references -- read and understand `dbml` file -- lookup the every folder - -## tasks - -Thanks - - - ---- - - -please take a look in `schema.dbml` and `schema.json`, -associate the collection from json file to the table in dbml file - -please modify the `schema.dbml` to align with `schema.json` - -to the collection `QuizLPCategories` align the dbml file in the previous prompt - - ---- - -please revise - -please revise -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx` `interface LpCategory` - -to the collection `QuizLPCategories` align the dbml file in the previous prompt - - -please modify `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/lp_categories/_constants.tsx` - -to follow the type definition in `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx`, the constant `defaultLpCategory` - ---- - -the constants file (`@/constants`) was `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/constants.ts` - -please help to fix the `tsx` files in folder `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/QuizMFCategories`, -the `COL` constants is wrongly used, it should refer to `COL_QUIZ_MF_CATEGORIES`. thanks - - -please update the `COL_XXXX` TO COL_MF_CATEGORIES diff --git a/002_source/cms/src/db/schema.json b/002_source/cms/src/db/schema.json index 9c2202f..c16b1b7 100644 --- a/002_source/cms/src/db/schema.json +++ b/002_source/cms/src/db/schema.json @@ -639,6 +639,58 @@ "system": false, "type": "relation" }, + { + "hidden": false, + "id": "json2115670734", + "maxSize": 0, + "name": "billingAddress", + "presentable": false, + "required": false, + "system": false, + "type": "json" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text922858135", + "max": 0, + "min": 0, + "name": "timezone", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text3571151285", + "max": 0, + "min": 0, + "name": "language", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text1767278655", + "max": 0, + "min": 0, + "name": "currency", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, { "hidden": false, "id": "autodate2990389176", @@ -2170,6 +2222,396 @@ "indexes": [], "system": false }, + { + "id": "pbc_491894781", + "listRule": "", + "viewRule": "", + "createRule": "", + "updateRule": "", + "deleteRule": "", + "name": "Students", + "type": "base", + "fields": [ + { + "autogeneratePattern": "[a-z0-9]{15}", + "hidden": false, + "id": "text3208210256", + "max": 15, + "min": 15, + "name": "id", + "pattern": "^[a-z0-9]+$", + "presentable": false, + "primaryKey": true, + "required": true, + "system": true, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text1579384326", + "max": 0, + "min": 0, + "name": "name", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text3885137012", + "max": 0, + "min": 0, + "name": "email", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text1146066909", + "max": 0, + "min": 0, + "name": "phone", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "hidden": false, + "id": "number1813778413", + "max": null, + "min": null, + "name": "quota", + "onlyInt": false, + "presentable": false, + "required": false, + "system": false, + "type": "number" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text2063623452", + "max": 0, + "min": 0, + "name": "status", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "hidden": false, + "id": "file507207115", + "maxSelect": 1, + "maxSize": 0, + "mimeTypes": [], + "name": "avatar_file", + "presentable": false, + "protected": false, + "required": false, + "system": false, + "thumbs": [], + "type": "file" + }, + { + "cascadeDelete": false, + "collectionId": "_pb_users_auth_", + "hidden": false, + "id": "relation2809058197", + "maxSelect": 1, + "minSelect": 0, + "name": "user_id", + "presentable": false, + "required": false, + "system": false, + "type": "relation" + }, + { + "hidden": false, + "id": "json2115670734", + "maxSize": 0, + "name": "billingAddress", + "presentable": false, + "required": false, + "system": false, + "type": "json" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text922858135", + "max": 0, + "min": 0, + "name": "timezone", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text3571151285", + "max": 0, + "min": 0, + "name": "language", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text1767278655", + "max": 0, + "min": 0, + "name": "currency", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "hidden": false, + "id": "autodate2990389176", + "name": "created", + "onCreate": true, + "onUpdate": false, + "presentable": false, + "system": false, + "type": "autodate" + }, + { + "hidden": false, + "id": "autodate3332085495", + "name": "updated", + "onCreate": true, + "onUpdate": true, + "presentable": false, + "system": false, + "type": "autodate" + } + ], + "indexes": [], + "system": false + }, + { + "id": "pbc_1413424569", + "listRule": "", + "viewRule": "", + "createRule": "", + "updateRule": "", + "deleteRule": "", + "name": "Teachers", + "type": "base", + "fields": [ + { + "autogeneratePattern": "[a-z0-9]{15}", + "hidden": false, + "id": "text3208210256", + "max": 15, + "min": 15, + "name": "id", + "pattern": "^[a-z0-9]+$", + "presentable": false, + "primaryKey": true, + "required": true, + "system": true, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text1579384326", + "max": 0, + "min": 0, + "name": "name", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text3885137012", + "max": 0, + "min": 0, + "name": "email", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text1146066909", + "max": 0, + "min": 0, + "name": "phone", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "hidden": false, + "id": "number1813778413", + "max": null, + "min": null, + "name": "quota", + "onlyInt": false, + "presentable": false, + "required": false, + "system": false, + "type": "number" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text2063623452", + "max": 0, + "min": 0, + "name": "status", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "hidden": false, + "id": "file507207115", + "maxSelect": 1, + "maxSize": 0, + "mimeTypes": [], + "name": "avatar_file", + "presentable": false, + "protected": false, + "required": false, + "system": false, + "thumbs": [], + "type": "file" + }, + { + "cascadeDelete": false, + "collectionId": "_pb_users_auth_", + "hidden": false, + "id": "relation2809058197", + "maxSelect": 1, + "minSelect": 0, + "name": "user_id", + "presentable": false, + "required": false, + "system": false, + "type": "relation" + }, + { + "hidden": false, + "id": "json2115670734", + "maxSize": 0, + "name": "billingAddress", + "presentable": false, + "required": false, + "system": false, + "type": "json" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text922858135", + "max": 0, + "min": 0, + "name": "timezone", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text3571151285", + "max": 0, + "min": 0, + "name": "language", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "autogeneratePattern": "", + "hidden": false, + "id": "text1767278655", + "max": 0, + "min": 0, + "name": "currency", + "pattern": "", + "presentable": false, + "primaryKey": false, + "required": false, + "system": false, + "type": "text" + }, + { + "hidden": false, + "id": "autodate2990389176", + "name": "created", + "onCreate": true, + "onUpdate": false, + "presentable": false, + "system": false, + "type": "autodate" + }, + { + "hidden": false, + "id": "autodate3332085495", + "name": "updated", + "onCreate": true, + "onUpdate": true, + "presentable": false, + "system": false, + "type": "autodate" + } + ], + "indexes": [], + "system": false + }, { "id": "pbc_1305841361", "listRule": "",