diff --git a/.env.example b/.env.example index 3a828f15..d0d9c04a 100644 --- a/.env.example +++ b/.env.example @@ -18,7 +18,7 @@ DB_SYNCHRONIZE=true DB_ENABLE_SSL=false PORT=8080 LOG_LEVEL=debug -JWT_EXPIRES_DAY=30d +JWT_EXPIRES_DAY=7d JWT_SECRET=hexschool666 FIREBASE_STORAGE_BUCKET='' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 3ea6ff53..00000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,142 +0,0 @@ -name: Check -on: - push: - - -jobs: - build : - name: build - runs-on: ubuntu-latest - steps: - - name: Checkout to Repo Directory - uses: actions/checkout@v4 - - name: Use Node.js 24 - uses: actions/setup-node@v6 - with: - node-version: '24' - cache: 'npm' - cache-dependency-path: backend/package-lock.json - - name: Restore cache node modules - id: cache - uses: actions/cache/restore@v4 - with: - path: backend/node_modules - key: ${{ runner.os }}-node-backend-${{ hashFiles('package-lock.json') }} - - name: Install dependencies - working-directory: backend - if: steps.cache.outputs.cache-hit != 'true' - run: npm ci - - name: update cache node modules - if: steps.cache.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 - with: - path: backend/node_modules - key: ${{ runner.os }}-node-backend-${{ hashFiles('package-lock.json') }} - # eslint-scan : - # name: Eslint Scanning - # needs: [build] - # runs-on: ubuntu-latest - # steps: - # - name: Checkout to Repo Directory - # uses: actions/checkout@v4 - # - name: Use Node.js 22 - # uses: actions/setup-node@v6 - # with: - # node-version: '22' - # cache: 'npm' - # cache-dependency-path: backend/package-lock.json - # - name: Restore cache node modules - # id: cache - # uses: actions/cache/restore@v4 - # with: - # path: backend/node_modules - # key: ${{ runner.os }}-node-backend-${{ hashFiles('package-lock.json') }} - # restore-keys: | - # ${{ runner.os }}-node-backend- - # - name: Eslint Scan - # uses: reviewdog/action-eslint@v1 - # with: - # workdir: ./backend - # reporter: github-check - integration-test: - name: Run integration Test - needs: [build] - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: write - statuses: write - env: - DB_USERNAME: root - DB_DATABASE: test - DB_PASSWORD: test - DB_HOST: localhost - DB_PORT: 5432 - services: - postgres: - image: postgres:17-alpine - ports: - - 5432:5432 - env: - POSTGRES_USER: ${{ env.DB_USERNAME }} - POSTGRES_PASSWORD: ${{ env.DB_PASSWORD }} - POSTGRES_DB: ${{ env.DB_DATABASE }} - steps: - - name: Checkout to Repo Directory - uses: actions/checkout@v4 - - name: Use Node.js 24 - uses: actions/setup-node@v6 - with: - node-version: '24' - cache: 'npm' - cache-dependency-path: backend/package-lock.json - - name: Restore cache node modules - id: cache - uses: actions/cache/restore@v4 - with: - path: backend/node_modules - key: ${{ runner.os }}-node-backend-${{ hashFiles('package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node-backend- - - name: Make env file - uses: SpicyPizza/create-envfile@v1 - with: - envkey_NODE_ENV: production - envkey_DB_HOST: ${{ env.DB_HOST }} - envkey_DB_PORT: ${{ env.DB_PORT }} - envkey_DB_DATABASE: ${{ env.DB_DATABASE }} - envkey_DB_USERNAME: ${{ env.DB_USERNAME }} - envkey_DB_PASSWORD: ${{ env.DB_PASSWORD }} - envkey_DB_SYNCHRONIZE: true - envkey_DB_ENABLE_SSL: false - envkey_JWT_SECRET: hexschool666 - envkey_JWT_EXPIRES_DAY: 30d - envkey_LOG_LEVEL: debug - envkey_FIREBASE_SERVICE_ACCOUNT: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }} - envkey_FIREBASE_STORAGE_BUCKET: ${{ secrets.FIREBASE_STORAGE_BUCKET }} - envkey_PORT: 3000 - directory: backend - file_name: .env - # - name: init schema - # working-directory: backend - # run: npm run init:schema - - name: test server - working-directory: backend - run: npm run test:integration - - name: upload coverage report - uses: actions/upload-artifact@v4 - with: - name: IntegrationTest Coverage report - path: backend/coverage - retention-days: 1 - - name: Integration Test Coverage monitor - uses: slavcodev/coverage-monitor-action@v1 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - coverage_path: "backend/coverage/clover.xml" - threshold_alert: 10 - threshold_warning: 50 - comment_context: 'Integration Test Report' - - - \ No newline at end of file diff --git a/.github/workflows/validate-advanced-missions.yml b/.github/workflows/validate-advanced-missions.yml new file mode 100644 index 00000000..408088c5 --- /dev/null +++ b/.github/workflows/validate-advanced-missions.yml @@ -0,0 +1,152 @@ +name: Validate Advanced Missions + +on: + push: + branches: ['*'] + pull_request: + branches: ['*'] + +jobs: + validate-screenshots: + name: Validate Advanced Missions Screenshots + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Check screenshots folder exists + run: | + echo "๐Ÿ“ ๆชขๆŸฅ screenshots ่ณ‡ๆ–™ๅคพๆ˜ฏๅฆๅญ˜ๅœจ" + if [ -d "screenshots" ]; then + echo "โœ… screenshots ่ณ‡ๆ–™ๅคพๅญ˜ๅœจ" + else + echo "โš ๏ธ screenshots ่ณ‡ๆ–™ๅคพไธๅญ˜ๅœจ๏ผŒ่ทณ้Ž้€ฒ้šŽไปปๅ‹™้ฉ—่ญ‰" + echo "๐Ÿ’ก ๆ็คบ๏ผšๅฆ‚ๆžœๆ‚จๅชๅฎŒๆˆๅˆ้šŽไปปๅ‹™ (LV1)๏ผŒๅฏไปฅๅฟฝ็•ฅๆญคๆชขๆŸฅ" + echo "SKIP_VALIDATION=true" >> $GITHUB_ENV + fi + + - name: Check screenshot 01 - Register + if: env.SKIP_VALIDATION != 'true' + run: | + echo "๐Ÿ“‹ ๆˆชๅœ– 1๏ผšๆชขๆŸฅ่จปๅ†ŠๆˆๅŠŸๆˆชๅœ–" + if [ -f "screenshots/01-register.png" ] || [ -f "screenshots/01-register.jpg" ] || [ -f "screenshots/01-register.jpeg" ]; then + echo "โœ… ้€š้Ž๏ผš01-register ๆˆชๅœ–ๅทฒไธŠๅ‚ณ" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ไธŠๅ‚ณ screenshots/01-register.png๏ผˆๅ…ฉๅ€‹ๅธณ่™Ÿ่จปๅ†ŠๆˆๅŠŸ๏ผ‰" + exit 1 + fi + + - name: Check screenshot 02 - Add Credit Package + if: env.SKIP_VALIDATION != 'true' + run: | + echo "๐Ÿ“‹ ๆˆชๅœ– 2๏ผšๆชขๆŸฅๆ–ฐๅขž็ต„ๅˆๅŒ…ๆ–นๆกˆๆˆชๅœ–" + if [ -f "screenshots/02-add-credit-package.png" ] || [ -f "screenshots/02-add-credit-package.jpg" ] || [ -f "screenshots/02-add-credit-package.jpeg" ]; then + echo "โœ… ้€š้Ž๏ผš02-add-credit-package ๆˆชๅœ–ๅทฒไธŠๅ‚ณ" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ไธŠๅ‚ณ screenshots/02-add-credit-package.png๏ผˆDBeaver ๆ–ฐๅขž็ต„ๅˆๅŒ…ๆ–นๆกˆๆˆๅŠŸ๏ผ‰" + exit 1 + fi + + - name: Check screenshot 03 - Add Skill + if: env.SKIP_VALIDATION != 'true' + run: | + echo "๐Ÿ“‹ ๆˆชๅœ– 3๏ผšๆชขๆŸฅๆ–ฐๅขžๆŠ€่ƒฝๆˆชๅœ–" + if [ -f "screenshots/03-add-skill.png" ] || [ -f "screenshots/03-add-skill.jpg" ] || [ -f "screenshots/03-add-skill.jpeg" ]; then + echo "โœ… ้€š้Ž๏ผš03-add-skill ๆˆชๅœ–ๅทฒไธŠๅ‚ณ" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ไธŠๅ‚ณ screenshots/03-add-skill.png๏ผˆๅพŒๅฐๆ–ฐๅขžๆŠ€่ƒฝๆˆๅŠŸ๏ผ‰" + exit 1 + fi + + - name: Check screenshot 04 - Upgrade Coach + if: env.SKIP_VALIDATION != 'true' + run: | + echo "๐Ÿ“‹ ๆˆชๅœ– 4๏ผšๆชขๆŸฅๅ‡็ดšๆ•™็ทดๆˆชๅœ–" + if [ -f "screenshots/04-upgrade-coach.png" ] || [ -f "screenshots/04-upgrade-coach.jpg" ] || [ -f "screenshots/04-upgrade-coach.jpeg" ]; then + echo "โœ… ้€š้Ž๏ผš04-upgrade-coach ๆˆชๅœ–ๅทฒไธŠๅ‚ณ" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ไธŠๅ‚ณ screenshots/04-upgrade-coach.png๏ผˆๆ•™็ทด่ณ‡ๆ ผ็ฎก็†ๅ‡็ดšๆˆๅŠŸ๏ผ‰" + exit 1 + fi + + - name: Check screenshot 05 - Create Course + if: env.SKIP_VALIDATION != 'true' + run: | + echo "๐Ÿ“‹ ๆˆชๅœ– 5๏ผšๆชขๆŸฅๆ•™็ทด้–‹่ชฒๆˆชๅœ–" + if [ -f "screenshots/05-create-course.png" ] || [ -f "screenshots/05-create-course.jpg" ] || [ -f "screenshots/05-create-course.jpeg" ]; then + echo "โœ… ้€š้Ž๏ผš05-create-course ๆˆชๅœ–ๅทฒไธŠๅ‚ณ" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ไธŠๅ‚ณ screenshots/05-create-course.png๏ผˆๆ•™็ทด้–‹่ชฒๆˆๅŠŸ๏ผ‰" + exit 1 + fi + + - name: Check screenshot 06 - Buy Credits + if: env.SKIP_VALIDATION != 'true' + run: | + echo "๐Ÿ“‹ ๆˆชๅœ– 6๏ผšๆชขๆŸฅ่ณผ่ฒทๅ ‚ๆ•ธๆˆชๅœ–" + if [ -f "screenshots/06-buy-credits.png" ] || [ -f "screenshots/06-buy-credits.jpg" ] || [ -f "screenshots/06-buy-credits.jpeg" ]; then + echo "โœ… ้€š้Ž๏ผš06-buy-credits ๆˆชๅœ–ๅทฒไธŠๅ‚ณ" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ไธŠๅ‚ณ screenshots/06-buy-credits.png๏ผˆๅญธๅ“ก่ณผ่ฒทๅ ‚ๆ•ธๆˆๅŠŸ๏ผ‰" + exit 1 + fi + + - name: Check screenshot 07 - Book Course + if: env.SKIP_VALIDATION != 'true' + run: | + echo "๐Ÿ“‹ ๆˆชๅœ– 7๏ผšๆชขๆŸฅ้ ็ด„่ชฒ็จ‹ๆˆชๅœ–" + if [ -f "screenshots/07-book-course.png" ] || [ -f "screenshots/07-book-course.jpg" ] || [ -f "screenshots/07-book-course.jpeg" ]; then + echo "โœ… ้€š้Ž๏ผš07-book-course ๆˆชๅœ–ๅทฒไธŠๅ‚ณ" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ไธŠๅ‚ณ screenshots/07-book-course.png๏ผˆๅญธๅ“ก้ ็ด„่ชฒ็จ‹ๆˆๅŠŸ๏ผ‰" + exit 1 + fi + + - name: Check screenshot 08 - Booking Record + if: env.SKIP_VALIDATION != 'true' + run: | + echo "๐Ÿ“‹ ๆˆชๅœ– 8๏ผšๆชขๆŸฅ้ ็ด„็ด€้Œ„ๆˆชๅœ–" + if [ -f "screenshots/08-booking-record.png" ] || [ -f "screenshots/08-booking-record.jpg" ] || [ -f "screenshots/08-booking-record.jpeg" ]; then + echo "โœ… ้€š้Ž๏ผš08-booking-record ๆˆชๅœ–ๅทฒไธŠๅ‚ณ" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ไธŠๅ‚ณ screenshots/08-booking-record.png๏ผˆ้ ็ด„็ด€้Œ„็•ซ้ข๏ผ‰" + exit 1 + fi + + - name: All advanced missions completed + if: env.SKIP_VALIDATION != 'true' + run: | + echo "" + echo "๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰ ๆญๅ–œ๏ผ้€ฒ้šŽไปปๅ‹™ๆˆชๅœ–ๅ…จ้ƒจไธŠๅ‚ณๅฎŒๆˆ๏ผ๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰" + echo "" + echo "โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—" + echo "โ•‘ ้€ฒ้šŽไปปๅ‹™ๆˆชๅœ–้ฉ—่ญ‰็ตๆžœ โ•‘" + echo "โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ" + echo "โ•‘ ๆˆชๅœ– 1๏ผšๅ…ฉๅ€‹ๅธณ่™Ÿ่จปๅ†ŠๆˆๅŠŸ โœ… ๅทฒไธŠๅ‚ณ โ•‘" + echo "โ•‘ ๆˆชๅœ– 2๏ผšDBeaver ๆ–ฐๅขž็ต„ๅˆๅŒ…ๆ–นๆกˆๆˆๅŠŸ โœ… ๅทฒไธŠๅ‚ณ โ•‘" + echo "โ•‘ ๆˆชๅœ– 3๏ผšๅพŒๅฐๆ–ฐๅขžๆŠ€่ƒฝๆˆๅŠŸ โœ… ๅทฒไธŠๅ‚ณ โ•‘" + echo "โ•‘ ๆˆชๅœ– 4๏ผšๆ•™็ทด่ณ‡ๆ ผ็ฎก็†ๅ‡็ดšๆˆๅŠŸ โœ… ๅทฒไธŠๅ‚ณ โ•‘" + echo "โ•‘ ๆˆชๅœ– 5๏ผšๆ•™็ทด้–‹่ชฒๆˆๅŠŸ โœ… ๅทฒไธŠๅ‚ณ โ•‘" + echo "โ•‘ ๆˆชๅœ– 6๏ผšๅญธๅ“ก่ณผ่ฒทๅ ‚ๆ•ธๆˆๅŠŸ โœ… ๅทฒไธŠๅ‚ณ โ•‘" + echo "โ•‘ ๆˆชๅœ– 7๏ผšๅญธๅ“ก้ ็ด„่ชฒ็จ‹ๆˆๅŠŸ โœ… ๅทฒไธŠๅ‚ณ โ•‘" + echo "โ•‘ ๆˆชๅœ– 8๏ผš้ ็ด„็ด€้Œ„็•ซ้ข โœ… ๅทฒไธŠๅ‚ณ โ•‘" + echo "โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ" + echo "โ•‘ โœ… ๅ…จ้ƒจ 8 ๅผตๆˆชๅœ–ๅทฒไธŠๅ‚ณ๏ผ โ•‘" + echo "โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" + echo "" + echo "๐Ÿ† ๆญๅ–œๅฎŒๆˆ LV2 ้€ฒ้šŽไปปๅ‹™๏ผ" + + - name: Skip message + if: env.SKIP_VALIDATION == 'true' + run: | + echo "" + echo "โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—" + echo "โ•‘ ้€ฒ้šŽไปปๅ‹™ๆˆชๅœ–้ฉ—่ญ‰็ตๆžœ โ•‘" + echo "โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ" + echo "โ•‘ โš ๏ธ ๆœชๅตๆธฌๅˆฐ screenshots ่ณ‡ๆ–™ๅคพ โ•‘" + echo "โ•‘ โ•‘" + echo "โ•‘ ๅฆ‚ๆžœๆ‚จๅชๅฎŒๆˆ LV1 ๅˆ้šŽไปปๅ‹™๏ผŒๅฏไปฅๅฟฝ็•ฅๆญค่จŠๆฏ โ•‘" + echo "โ•‘ ๅฆ‚ๆžœๆ‚จ่ฆๅฎŒๆˆ LV2 ้€ฒ้šŽไปปๅ‹™๏ผŒ่ซ‹๏ผš โ•‘" + echo "โ•‘ 1. ๅปบ็ซ‹ screenshots ่ณ‡ๆ–™ๅคพ โ•‘" + echo "โ•‘ 2. ไธŠๅ‚ณ 8 ๅผตๆˆชๅœ–๏ผˆ01-register.png ~ 08-booking-record.png๏ผ‰โ•‘" + echo "โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" diff --git a/.github/workflows/validate-beginner-missions.yml b/.github/workflows/validate-beginner-missions.yml new file mode 100644 index 00000000..6acf8f85 --- /dev/null +++ b/.github/workflows/validate-beginner-missions.yml @@ -0,0 +1,104 @@ +name: ๅˆ้šŽไปปๅ‹™้ฉ—่ญ‰ + +on: + push: + branches: ['*'] + pull_request: + branches: ['*'] + +jobs: + validate-missions: + name: ้ฉ—่ญ‰ๅˆ้šŽไปปๅ‹™ 7 ้กŒ + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Task 1 - Check website title + run: | + echo "๐Ÿ“‹ ้กŒ็›ฎ 1๏ผšๆชขๆŸฅ็ถฒ็ซ™ Title" + if grep -q "LiveFit" frontend/index.html; then + echo "โœ… ้€š้Ž๏ผšTitle ๅทฒๆ”น็‚บ LiveFit" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ๅฐ‡ frontend/index.html ไธญ็š„ LiveFit+ ๆ”น็‚บ LiveFit" + exit 1 + fi + + - name: Task 2 - Check logo image + run: | + echo "๐Ÿ“‹ ้กŒ็›ฎ 2๏ผšๆชขๆŸฅ็ถฒ็ซ™ Logo" + if grep -q "logo-text-v2.png" frontend/src/layouts/LayoutHeader.vue; then + echo "โœ… ้€š้Ž๏ผšLogo ๅทฒๆ”น็‚บ logo-text-v2.png" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ๅฐ‡ frontend/src/layouts/LayoutHeader.vue ไธญ็š„ logo-text.png ๆ”น็‚บ logo-text-v2.png" + exit 1 + fi + + - name: Task 3 - Check JWT expiration + run: | + echo "๐Ÿ“‹ ้กŒ็›ฎ 3๏ผšๆชขๆŸฅ Token ้ŽๆœŸ่จญๅฎš" + if grep -q "JWT_EXPIRES_DAY=7d" .env.example; then + echo "โœ… ้€š้Ž๏ผšJWT_EXPIRES_DAY ๅทฒๆ”น็‚บ 7d" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ๅฐ‡ .env.example ไธญ็š„ JWT_EXPIRES_DAY=30d ๆ”น็‚บ JWT_EXPIRES_DAY=7d" + exit 1 + fi + + - name: Task 4 - Check Entity comment + run: | + echo "๐Ÿ“‹ ้กŒ็›ฎ 4๏ผšๆชขๆŸฅ Entity ๆฌ„ไฝ่ชชๆ˜Ž" + if head -10 backend/entities/CreditPackages.js | grep -q "ๅ ‚ๆ•ธๆ–นๆกˆ่ณ‡ๆ–™่กจ"; then + echo "โœ… ้€š้Ž๏ผšๅทฒๆ–ฐๅขžๆฌ„ไฝ่ชชๆ˜Ž่จป่งฃ" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ๅœจ backend/entities/CreditPackages.js ๆช”ๆกˆๆœ€ไธŠๆ–นๆ–ฐๅขžๆฌ„ไฝ่ชชๆ˜Ž่จป่งฃ" + exit 1 + fi + + - name: Task 5 - Check password length + run: | + echo "๐Ÿ“‹ ้กŒ็›ฎ 5๏ผšๆชขๆŸฅๅฏ†็ขผ้•ทๅบฆ้™ๅˆถ" + if grep -q "\.{10,16}" backend/controllers/users.js; then + echo "โœ… ้€š้Ž๏ผšๅฏ†็ขผ้•ทๅบฆๅทฒๆ”น็‚บ 10-16" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ๅฐ‡ backend/controllers/users.js ไธญ็š„ .{8,16} ๆ”น็‚บ .{10,16}" + exit 1 + fi + + - name: Task 6 - Check API total field + run: | + echo "๐Ÿ“‹ ้กŒ็›ฎ 6๏ผšๆชขๆŸฅ API ๅ›žๅ‚ณ็ธฝ็ญ†ๆ•ธ" + if grep -q "total: creditPackage.length" backend/controllers/creditPackage.js; then + echo "โœ… ้€š้Ž๏ผšๅทฒๆ–ฐๅขž total ๆฌ„ไฝ" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ๅœจ backend/controllers/creditPackage.js ็š„ getAll ๅ‡ฝๆ•ธไธญๆ–ฐๅขž total: creditPackage.length" + exit 1 + fi + + - name: Task 7 - Check healthcheck response + run: | + echo "๐Ÿ“‹ ้กŒ็›ฎ 7๏ผšๆชขๆŸฅๅฅๅบทๆชขๆŸฅๅ›žๅ‚ณๆ ผๅผ" + if grep -A5 "app.get('/healthcheck'" backend/app.js | grep -q "res.status(200).json"; then + echo "โœ… ้€š้Ž๏ผšhealthcheck ๅทฒๆ”น็‚บ JSON ๆ ผๅผ" + else + echo "โŒ ๅคฑๆ•—๏ผš่ซ‹ๅฐ‡ backend/app.js ไธญ็š„ healthcheck ่ทฏ็”ฑๆ”น็‚บๅ›žๅ‚ณ JSON ๆ ผๅผ" + exit 1 + fi + + - name: All missions completed + run: | + echo "" + echo "๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰ ๆญๅ–œ๏ผๅˆ้šŽไปปๅ‹™ๅ…จ้ƒจ้€š้Ž๏ผ๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰" + echo "" + echo "โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—" + echo "โ•‘ ๅˆ้šŽไปปๅ‹™้ฉ—่ญ‰็ตๆžœ โ•‘" + echo "โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ" + echo "โ•‘ ้กŒ็›ฎ 1๏ผšไฟฎๆ”น็ถฒ็ซ™ Title โœ… ้€š้Ž โ•‘" + echo "โ•‘ ้กŒ็›ฎ 2๏ผšๆ›ดๆ›็ถฒ็ซ™ Logo โœ… ้€š้Ž โ•‘" + echo "โ•‘ ้กŒ็›ฎ 3๏ผšไฟฎๆ”น Token ้ŽๆœŸ่จญๅฎš โœ… ้€š้Ž โ•‘" + echo "โ•‘ ้กŒ็›ฎ 4๏ผšๆ–ฐๅขž Entity ๆฌ„ไฝ่ชชๆ˜Ž โœ… ้€š้Ž โ•‘" + echo "โ•‘ ้กŒ็›ฎ 5๏ผšไฟฎๆ”นๅฏ†็ขผ้•ทๅบฆ้™ๅˆถ โœ… ้€š้Ž โ•‘" + echo "โ•‘ ้กŒ็›ฎ 6๏ผšๆ–ฐๅขž API ๅ›žๅ‚ณ็ธฝ็ญ†ๆ•ธ โœ… ้€š้Ž โ•‘" + echo "โ•‘ ้กŒ็›ฎ 7๏ผšไฟฎๆ”นๅฅๅบทๆชขๆŸฅๅ›žๅ‚ณๆ ผๅผ โœ… ้€š้Ž โ•‘" + echo "โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ" + echo "โ•‘ โœ… ๅ…จ้ƒจ 7 ้กŒ้€š้Ž๏ผ โ•‘" + echo "โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•" diff --git a/backend/app.js b/backend/app.js index 9e3acb6d..8a922a15 100644 --- a/backend/app.js +++ b/backend/app.js @@ -28,8 +28,10 @@ app.use(pinoHttp({ app.use(express.static(path.join(__dirname, 'public'))) app.get('/healthcheck', (req, res) => { - res.status(200) - res.send('OK') + res.status(200).json({ + status: 'success', + message: 'OK' +}) }) app.use('/api/credit-package', creditPackageRouter) app.use('/api/coaches/skill', skillRouter) diff --git a/backend/controllers/creditPackage.js b/backend/controllers/creditPackage.js index 53b588e3..b616c87e 100644 --- a/backend/controllers/creditPackage.js +++ b/backend/controllers/creditPackage.js @@ -22,6 +22,7 @@ class CreditPackageController { res.status(200).json({ status: 'success', data: creditPackage + total: creditPackage.length }) } catch (error) { logger.error(error) diff --git a/backend/controllers/users.js b/backend/controllers/users.js index e95eb4aa..d7d9b31a 100644 --- a/backend/controllers/users.js +++ b/backend/controllers/users.js @@ -6,7 +6,7 @@ const { dataSource } = require('../db/data-source') const logger = require('../utils/logger')('UsersController') const generateJWT = require('../utils/generateJWT') -const passwordPattern = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,16}/ +const passwordPattern = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{10,16}/ function isUndefined (value) { return value === undefined diff --git a/backend/entities/CreditPackages.js b/backend/entities/CreditPackages.js index 32a38695..6d7e3c41 100644 --- a/backend/entities/CreditPackages.js +++ b/backend/entities/CreditPackages.js @@ -1,3 +1,13 @@ +/** + * ๅ ‚ๆ•ธๆ–นๆกˆ่ณ‡ๆ–™่กจ + * + * ๆฌ„ไฝ่ชชๆ˜Ž๏ผš + * - id: ๆ–นๆกˆ็ทจ่™Ÿ๏ผˆUUID๏ผ‰ + * - name: ๆ–นๆกˆๅ็จฑ + * - credit_amount: ๅŒ…ๅซๅ ‚ๆ•ธ + * - price: ๆ–นๆกˆๅƒนๆ ผ + * - createdAt: ๅปบ็ซ‹ๆ™‚้–“ + */ const { EntitySchema } = require('typeorm') module.exports = new EntitySchema({ diff --git a/frontend/index.html b/frontend/index.html index 59fa7bc6..68a88db1 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -4,7 +4,7 @@ - LiveFit+ + LiveFit
diff --git a/frontend/public/logo-text-v2.png b/frontend/public/logo-text-v2.png new file mode 100644 index 00000000..b8cdfa36 Binary files /dev/null and b/frontend/public/logo-text-v2.png differ diff --git a/frontend/src/layouts/LayoutFooter.vue b/frontend/src/layouts/LayoutFooter.vue index 6e66f63e..2e3e3344 100644 --- a/frontend/src/layouts/LayoutFooter.vue +++ b/frontend/src/layouts/LayoutFooter.vue @@ -5,7 +5,7 @@ class="flex justify-between items-center h-12 border-b border-neutral-300 pt-16 pb-12" > - LiveFit+ + LiveFit+ LiveFit+ diff --git a/frontend/src/layouts/LayoutHeader.vue b/frontend/src/layouts/LayoutHeader.vue index 6069f35e..45865e35 100644 --- a/frontend/src/layouts/LayoutHeader.vue +++ b/frontend/src/layouts/LayoutHeader.vue @@ -8,7 +8,7 @@ @click="closeMobileMenu" class="flex items-center" > - LiveFit+ + LiveFit+ LiveFit+ diff --git a/screenshots/01-register.png b/screenshots/01-register.png new file mode 100644 index 00000000..e11d7d72 Binary files /dev/null and b/screenshots/01-register.png differ diff --git a/screenshots/02-add-credit-package.png b/screenshots/02-add-credit-package.png new file mode 100644 index 00000000..d015ce3b Binary files /dev/null and b/screenshots/02-add-credit-package.png differ diff --git a/screenshots/03-add-skill.png b/screenshots/03-add-skill.png new file mode 100644 index 00000000..655c2179 Binary files /dev/null and b/screenshots/03-add-skill.png differ diff --git a/screenshots/04-upgrade-coach.png b/screenshots/04-upgrade-coach.png new file mode 100644 index 00000000..ed4bc01b Binary files /dev/null and b/screenshots/04-upgrade-coach.png differ diff --git a/screenshots/05-create-course.png b/screenshots/05-create-course.png new file mode 100644 index 00000000..b99d7833 Binary files /dev/null and b/screenshots/05-create-course.png differ diff --git a/screenshots/06-buy-credits.png b/screenshots/06-buy-credits.png new file mode 100644 index 00000000..0a90c8a7 Binary files /dev/null and b/screenshots/06-buy-credits.png differ diff --git a/screenshots/07-book-course.png b/screenshots/07-book-course.png new file mode 100644 index 00000000..449aa227 Binary files /dev/null and b/screenshots/07-book-course.png differ diff --git a/screenshots/08-booking-record.png b/screenshots/08-booking-record.png new file mode 100644 index 00000000..533e6f18 Binary files /dev/null and b/screenshots/08-booking-record.png differ