diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..3cac6a0 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,54 @@ +# ๐Ÿ“ Pull Request Template + +## Description + + +--- + +## ๐Ÿš€ Type of Change +- [ ] ๐Ÿ› Bug Fix +- [ ] โœจ New Feature +- [ ] ๐Ÿ”’ Security / Vulnerability Patch +- [ ] ๐Ÿ’„ Redesign / Polish / Brand Alignment +- [ ] ๐Ÿงน Chore / Environment Scaffold + +--- + +## ๐Ÿ›ก๏ธ CREOVA Quality Assurance Checklist +*Before requesting a review or merging, verify all applicable checks are completed. Branch, PR, and merge every single time โ€” even for solo fixes.* + +### 1. Integrity & Real-World Truth (Anti-Fabrication Standards) +*We enforce a strict policy against misleading mock states, fake labels, or unpersisted UI changes.* +- [ ] **No "Live"/"Active" claims on static or simulated features:** any status label implying a real-time or fully-wired system is only used when that system is actually live. +- [ ] **Real backend persistence:** user-facing "Save" actions actually persist to the database, not just local/session state. +- [ ] **Actual pipelines (no fakes):** AI/voice/processing features use real backend pipelines rather than simulated or hardcoded frontends. +- [ ] **Transparent demo-mode labels:** any feature running on sample/seed data is honestly labeled as such โ€” no fabricated "live" framing. +- [ ] **Authorized admin access:** sensitive consoles and developer views have RBAC gates and are removed from general user navigation. + +### 2. Security & Database Integrity +- [ ] **Supabase JWT & Edge Functions:** edge-function authorization has been validated (`verify_jwt = true` enforced unless explicitly audited for public use). +- [ ] **Row-Level Security (RLS):** all new or modified Supabase tables have active RLS policies, especially for financial or personal data. +- [ ] **Migrations actually applied:** any new migration file has been run against the target environment, not just committed to git. +- [ ] **Clean upgrade/payment paths:** payment screens and upgrade options are fully validated; paid tiers cannot be granted for free. + +### 3. Performance, Layout & Localization +- [ ] **Robust offline handling (where applicable):** features preserve offline-created or offline-completed actions and do not silently discard them. +- [ ] **Copy & truncation quality:** UI strings are checked for localization accuracy and don't truncate awkwardly on small displays. +- [ ] **Visual constraints:** charts, SVGs, and layout components handle negative/zero-width constraints without rendering crashes. + +--- + +## ๐ŸŽฏ Target Branch +- [ ] **`dev`** (Active Development: where all features integrate first) +- [ ] **`staging`** (Dress Rehearsal: mirrors production to catch issues before launch) +- [ ] **`main`** (Sacred Production Branch: protected, user-facing live environment) + +--- + +## ๐Ÿงช Testing & Verification + + +--- + +## ๐Ÿ“ธ Screenshots / Recordings + diff --git a/.github/workflows/ci-validate.yml b/.github/workflows/ci-validate.yml new file mode 100644 index 0000000..627e304 --- /dev/null +++ b/.github/workflows/ci-validate.yml @@ -0,0 +1,23 @@ +name: CI/CD Branching Pipeline + +on: + push: + branches: [dev, staging, main] + pull_request: + branches: [dev, staging, main] + +jobs: + validate: + name: Validate Code Changes + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v2 + with: + version: 8 + - uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'pnpm' + - run: pnpm install --frozen-lockfile + - run: pnpm run build diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 92e3758..b35a868 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,17 +4,6 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false -overrides: - '@xmldom/xmldom': ^0.9.10 - lodash: ^4.18.1 - picomatch: ^4.0.4 - postcss: ^8.5.15 - rollup: ^4.60.4 - tar: ^7.5.15 - uuid: ^9.0.0 - vite: ^6.4.2 - yaml: ^2.9.0 - importers: .: @@ -1315,66 +1304,79 @@ packages: resolution: {integrity: sha512-DxH0P3wxm+Yzs/p3zrk9dw1rURu8p0Nv5+MRK/L7OtnLNg5rLZraSBFZ8iUXOd9f2BlhJyEpIZUH/emjq4UJ4g==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.61.0': resolution: {integrity: sha512-T6ZvMNe84kAz6TBWHC7hGAoEtzP1LWYw/AqayGWEF6uISt3Abk/st06LqRD9THd7Xz3NxzurUpzAuEAUbZf+nw==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.61.0': resolution: {integrity: sha512-q/4hzvQkDs8b4jIBab1pnLiiM0ayTZsN2amBFPDzuyZxjEd4wDwx0UJFYM3cOZzSf5Kw8fnWSprJzIBMkcR44Q==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.61.0': resolution: {integrity: sha512-vvYWX3akdEAY6km+9wAqFDnk6pQsbJKVnj7xawcvs/+fdlYBGp+U+Qq/lLfpIxYIZvZLHMAKD9HLdacSx/r3dw==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.61.0': resolution: {integrity: sha512-DePa5cqOxDP/Zp0VOXpeWaGew5iIv5DXp9NYbzkX5PFQyWVX9184WCTh3hvr/7lhXo8ZVlbFLkz8+o/q1dU6gA==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.61.0': resolution: {integrity: sha512-LV8aWMB8UChglMCEzs7RkN0GsH29RJaLLqwm9fCIjlqwxQTiWAqNcc7wjBkH31hV0PU/yVxGYvrYsgfea2qw6g==} cpu: [loong64] os: [linux] + libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.61.0': resolution: {integrity: sha512-QoNSnwQtaeNu5grdBbsL0tt1uyl5EnS8DA8Mr3nluMXbhdQNyhN+G4tBax7VCdxLKj8YJ0/4OO9Ho84jMnJtKA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.61.0': resolution: {integrity: sha512-/zZp5MKapIIApE8trN8qLGNSiRN9TUoaUZ1cmVu4XnVdd5LQLOXTtyi+vtfUbNnT3iyjzpPqYeKXmvJ+gJGYWw==} cpu: [ppc64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.61.0': resolution: {integrity: sha512-RbrzcD3aJ1k3UbtMRRBNwojdVVyXjuVAFTfn/xPa6EEl6GE9Sm/akPgFTb9aAC9pMKGJ6CtWxaGrqWcabH+ySg==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.61.0': resolution: {integrity: sha512-ZF+onDsBso8PJf1XaG9lB+O9RnBpKGnY6OrzC4CSHrtC1jb6jWLTKK4bRqdoCXHd22gyr2hiYmEAm8Wns/BOCw==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.61.0': resolution: {integrity: sha512-Atk0aSIk5Zx2Wuh9dgRQgLP0Koc8hOeYpbWryMXyk8G8/HmPkwPPkMqIIDhrXHHYqfUzSJA/I7IWSBv8xSmRBA==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.61.0': resolution: {integrity: sha512-0uMOcf3eZ5K+K4cYHkdxShFMPlPXCOdfDFEFn9dNYAEEd2cVvmOfH7zFgRVoDgmtQ1m9k5q7qfrHzyMAubKYUA==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.61.0': resolution: {integrity: sha512-mvFtE4A/t/7hRJ7X8Ozmu8FsIkAUat2nzl12pgU337BRmq87AQUJztwHz2Zv5/tjo9/C95E66CK03SI/ToEDJw==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openbsd-x64@4.61.0': resolution: {integrity: sha512-z9b9+aTxvt8n2rNltMPvyaUfB8NJ+CVyOrGK/MdIKHx7B+lXmZpm/XbRsU7Rpf3fRqJ2uS6mBJiJveCtq8LHDg==} @@ -1444,24 +1446,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.1.12': resolution: {integrity: sha512-V8pAM3s8gsrXcCv6kCHSuwyb/gPsd863iT+v1PGXC4fSL/OJqsKhfK//v8P+w9ThKIoqNbEnsZqNy+WDnwQqCA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.1.12': resolution: {integrity: sha512-xYfqYLjvm2UQ3TZggTGrwxjYaLB62b1Wiysw/YE3Yqbh86sOMoTn0feF98PonP7LtjsWOWcXEbGqDL7zv0uW8Q==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.1.12': resolution: {integrity: sha512-ha0pHPamN+fWZY7GCzz5rKunlv9L5R8kdh+YNvP5awe3LtuXb5nRi/H27GeL2U+TdhDOptU7T6Is7mdwh5Ar3A==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.1.12': resolution: {integrity: sha512-4tSyu3dW+ktzdEpuk6g49KdEangu3eCYoqPhWNsZgUhyegEda3M9rG0/j1GV/JjVVsj+lG7jWAyrTlLzd/WEBg==} @@ -1494,7 +1500,7 @@ packages: '@tailwindcss/vite@4.1.12': resolution: {integrity: sha512-4pt0AMFDx7gzIrAOIYgYP0KCBuKWqyW8ayrdiLEjoJTT4pKTjrzG/e4uzWtTLDziC+66R9wbUqZBccJalSE5vQ==} peerDependencies: - vite: ^6.4.2 + vite: ^5.2.0 || ^6 || ^7 '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1556,7 +1562,7 @@ packages: resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^6.4.2 + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 aria-hidden@1.2.6: resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} @@ -1742,7 +1748,7 @@ packages: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} peerDependencies: - picomatch: ^4.0.4 + picomatch: ^3 || ^4 peerDependenciesMeta: picomatch: optional: true @@ -1863,24 +1869,28 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.30.1: resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.30.1: resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.30.1: resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.30.1: resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} @@ -2125,6 +2135,7 @@ packages: recharts@2.15.2: resolution: {integrity: sha512-xv9lVztv3ingk7V3Jf05wfAZbM9Q2umJzu5t/cfnAK7LUslNrGT7LPBr74G+ok8kSCeFMaePmWMg0rcYOnczTw==} engines: {node: '>=14'} + deprecated: 1.x and 2.x branches are no longer active. Bump to Recharts v3 to receive latest features and bugfixes. See https://github.com/recharts/recharts/wiki/3.0-migration-guide peerDependencies: react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -2257,7 +2268,7 @@ packages: sugarss: '*' terser: ^5.16.0 tsx: ^4.8.1 - yaml: ^2.9.0 + yaml: ^2.4.2 peerDependenciesMeta: '@types/node': optional: true @@ -2292,6 +2303,10 @@ packages: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} + yaml@1.10.3: + resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} + engines: {node: '>= 6'} + yaml@2.9.0: resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} engines: {node: '>= 14.6'} @@ -3619,7 +3634,7 @@ snapshots: import-fresh: 3.3.1 parse-json: 5.2.0 path-type: 4.0.0 - yaml: 2.9.0 + yaml: 1.10.3 csstype@3.2.3: {} @@ -4237,4 +4252,7 @@ snapshots: yallist@5.0.0: {} - yaml@2.9.0: {} + yaml@1.10.3: {} + + yaml@2.9.0: + optional: true diff --git a/scripts/setup-git-pipeline.sh b/scripts/setup-git-pipeline.sh new file mode 100644 index 0000000..950fbf1 --- /dev/null +++ b/scripts/setup-git-pipeline.sh @@ -0,0 +1,101 @@ +#!/bin/bash +# setup-git-pipeline.sh +# Automates the local setup for a secure feature-dev-staging-main branching workflow. + +set -e + +# Print styled messages +log_info() { echo -e "\033[0;34m[INFO]\033[0m $1"; } +log_success() { echo -e "\033[0;32m[SUCCESS]\033[0m $1"; } +log_warn() { echo -e "\033[0;33m[WARNING]\033[0m $1"; } +log_error() { echo -e "\033[0;31m[ERROR]\033[0m $1"; exit 1; } + +# Step 1: Verify we are in a git repository or initialize one +if [ ! -d ".git" ]; then + log_info "No local Git repository found. Initializing..." + git init +else + log_info "Existing Git repository detected." +fi + +# Step 2: Ensure main branch exists +log_info "Ensuring 'main' branch exists..." + +# In Git >= 2.28, we can set default branch to main. +# If it's a new repository, we might not have a HEAD commit, so we create main. +current_branch=$(git symbolic-ref --short HEAD 2>/dev/null || echo "") + +if [ -z "$current_branch" ]; then + log_info "Repository is empty. Configuring 'main' as the default branch..." + # Attempt to use git checkout to create main + git checkout -b main 2>/dev/null || git checkout -b main --orphan 2>/dev/null || true + current_branch="main" +elif [ "$current_branch" = "master" ]; then + log_warn "Renaming legacy branch 'master' to 'main'..." + git branch -m master main + current_branch="main" +fi + +# Step 3: Create 'staging' and 'dev' branches +# Staging branch (if it doesn't exist, branch off main or current HEAD) +if git show-ref --quiet refs/heads/staging; then + log_info "Branch 'staging' already exists." +else + log_info "Creating 'staging' branch (the dress rehearsal)..." + git branch staging 2>/dev/null || git checkout -b staging 2>/dev/null || true +fi + +# Dev branch (if it doesn't exist) +if git show-ref --quiet refs/heads/dev; then + log_info "Branch 'dev' already exists." +else + log_info "Creating 'dev' branch (active development)..." + git branch dev 2>/dev/null || git checkout -b dev 2>/dev/null || true +fi + +# If we have commits, switch to dev as default workspace +if [ -n "$(git rev-parse --all 2>/dev/null)" ]; then + git checkout dev 2>/dev/null || true +fi + +# Step 4: Write local pre-push git hook to lock down 'main' and 'staging' +log_info "Installing local pre-push security hooks..." +HOOK_PATH=".git/hooks/pre-push" + +cat << 'EOF' > "$HOOK_PATH" +#!/bin/bash +# Local Git pre-push hook to prevent pushing directly to main or staging. +# Guided by: "You should never push directly to the main branch ever." + +protected_branches="main staging" +current_branch=$(git symbolic-ref --short HEAD 2>/dev/null) + +if [ -z "$current_branch" ]; then + exit 0 +fi + +for branch in $protected_branches; do + if [ "$current_branch" = "$branch" ]; then + echo -e "\n\033[0;31m[GIT PROTECT] Error: You are attempting to push directly to the protected branch '$branch'!\033[0m" + echo -e "Remember: 'Branch, PR, and merge every single time.'\n" + exit 1 + fi +done + +exit 0 +EOF + +chmod +x "$HOOK_PATH" +log_success "Pre-push safety hook active! Direct pushes to 'main' or 'staging' are blocked locally." + +# Step 5: Instructions +echo -e "\n=============================================" +log_success "Local Git Pipeline Setup Complete!" +echo -e "=============================================\n" +echo -e "Recommended Daily Workflow:" +echo -e " 1. Create feature branch: \033[0;32mgit checkout -b feature/your-feature-name\033[0m" +echo -e " 2. Work, commit, and push: \033[0;32mgit push origin feature/your-feature-name\033[0m" +echo -e " 3. Open Pull Request (PR) targeting \033[0;33mdev\033[0m on GitHub." +echo -e " 4. Merge dev into \033[0;35mstaging\033[0m (dress rehearsal testing) via PR." +echo -e " 5. Merge staging into \033[0;31mmain\033[0m (sacred production deployment) via PR." +echo -e "=============================================\n"