diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..4a7f284 --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +NEXT_PUBLIC_APP_URL=http://localhost:3000 +STRIPE_SECRET_KEY= +STRIPE_WEBHOOK_SECRET= +DATABASE_URL= diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..bffb357 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..9b77ea7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,40 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "" +labels: "" +assignees: "" +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: + +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- Version [e.g. 22] + +**Smartphone (please complete the following information):** + +- Device: [e.g. iPhone6] +- OS: [e.g. iOS8.1] +- Browser [e.g. stock browser, safari] +- Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 0000000..babf9b2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -0,0 +1,7 @@ +--- +name: Custom issue template +about: Describe this issue template's purpose here. +title: "" +labels: "" +assignees: "" +--- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..2bc5d5f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,19 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "" +labels: "" +assignees: "" +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/agents/my-agent.agent.md b/.github/agents/my-agent.agent.md new file mode 100644 index 0000000..39a8426 --- /dev/null +++ b/.github/agents/my-agent.agent.md @@ -0,0 +1,13 @@ +--- +# Fill in the fields below to create a basic custom agent for your repository. +# The Copilot CLI can be used for local testing: https://gh.io/customagents/cli +# To make this agent available, merge this file into the default repository branch. +# For format details, see: https://gh.io/customagents/config + +name: +description: +--- + +# My Agent + +Describe what your agent does here... diff --git a/.github/content.png b/.github/content.png new file mode 100644 index 0000000..a987999 Binary files /dev/null and b/.github/content.png differ diff --git a/.github/document.json b/.github/document.json new file mode 100644 index 0000000..475acc0 --- /dev/null +++ b/.github/document.json @@ -0,0 +1 @@ +{ "detail": "Not Found" } diff --git a/.github/instructions/*.instructions.md b/.github/instructions/*.instructions.md new file mode 100644 index 0000000..4fd7637 --- /dev/null +++ b/.github/instructions/*.instructions.md @@ -0,0 +1,47 @@ +# 📜 INSTRUKTION – YONI App (Überhochglitzer Edition) + +> Version 1.0 · Stand: 2025-11-11 +> Eigentum: piHOCH2 / YONI Projektgruppe +> Zweck: Vollständige Dokumentation für Aufbau, Betrieb, Pflege und ethische Leitung der YONI-App. + +--- + +## 🧩 1. Vision & Philosophie + +**YONI** ist ein digitaler, geschützter Raum für Menschen mit psychischer Belastung. +Ziel ist **Heilung durch Verbindung**, gestützt von Fachärzt:innen und einer liebevollen Community. + +Leitprinzipien: + +- 🟣 _Sicherheit_ – technischer und psychologischer Schutz. +- 💜 _Würde_ – jedes Individuum ist einzigartig und unantastbar. +- 🌌 _Transzendenz_ – Ästhetik als Brücke zwischen Innenwelt und Kosmos. +- 🧠 _Kompetenz_ – medizinisch fundierte Inhalte, geprüft von Fachpersonal. +- 🪶 _Leichtigkeit_ – Minimalismus, Barrierefreiheit, klare Sprache. + +--- + +## ⚙️ 2. Technische Übersicht + +| Ebene | Technologie | Beschreibung | +| -------------- | --------------------------------------- | ------------------------------ | +| **Frontend** | Next.js 14 (App Router) | SSR, Routing, Edge-API | +| **Styling** | TailwindCSS + Überhochglitzer-Theme | Tokens, Starfield, Animation | +| **Backend** | API Routes (Stripe, GitHub, Safety-Bot) | Event-Handling, Webhooks | +| **Deployment** | Vercel (Preview + Prod) | CI/CD | +| **Security** | CSP, HTTPS, RBAC, Secrets via Vercel | DSGVO-konform | +| **Monitoring** | Lighthouse CI, axe-core, Sentry | Qualität & A11y | +| **Data Layer** | Edge Storage / Supabase (optional)\*\* | Prototyp → persistente Gruppen | + +--- + +## 🚀 3. Setup-Anleitung + +### Lokale Umgebung + +```bash +git clone https://github.com/pappensex/YONI-app.git +cd YONI-app +npm install +npm run dev +``` diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..3ce84d5 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,14 @@ +## Summary + +- [ ] Intent beschrieben +- [ ] Breaking changes gekennzeichnet + +## Content Validation + +- [ ] `notion-template.json` durch CI validiert +- [ ] `launch_tasks.csv` Datumsformat `YYYY-MM-DD` +- [ ] README stimmt mit Properties/Views überein + +## Risks + +- [ ] Keine Secrets/Keys im Diff diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml new file mode 100644 index 0000000..db2f49b --- /dev/null +++ b/.github/workflows/automerge.yml @@ -0,0 +1,20 @@ +name: Auto Merge Autofix PRs +on: + pull_request: + types: [opened, reopened, synchronize, ready_for_review] + branches: ["**"] + +permissions: + pull-requests: write + contents: write + +jobs: + automerge: + if: github.actor == 'github-actions[bot]' && contains(github.event.pull_request.labels.*.name, 'autofix') + runs-on: ubuntu-latest + steps: + - name: Enable auto-merge when checks pass + run: gh pr merge $PR --auto --squash + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR: ${{ github.event.pull_request.number }} diff --git a/.github/workflows/content-auto-fix.yml b/.github/workflows/content-auto-fix.yml new file mode 100644 index 0000000..5bb5a3c --- /dev/null +++ b/.github/workflows/content-auto-fix.yml @@ -0,0 +1,61 @@ +name: Content Auto-Fix +on: + push: + paths: + - "project-ops/launch/**" + branches-ignore: + - "automation/content-fixes/**" + +permissions: + contents: write + pull-requests: write + +concurrency: + group: content-auto-fix-${{ github.ref }} + cancel-in-progress: true + +jobs: + autofix: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Install deps + run: npm ci --ignore-scripts --fund=false + + - name: Run auto-fixes + run: npm run fix:content + env: + CI: true + + - name: Check if something changed + id: diff + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + if git diff --quiet; then + echo "changed=false" >> $GITHUB_OUTPUT + else + echo "changed=true" >> $GITHUB_OUTPUT + fi + + - name: Create PR with fixes + if: steps.diff.outputs.changed == 'true' + uses: peter-evans/create-pull-request@v7 + with: + branch: automation/content-fixes/${{ github.run_id }} + title: "chore: auto-fix Notion/CSV content" + commit-message: "chore: auto-fix content [skip ci]" + body: | + Auto-generierte Korrekturen aus `npm run fix:content`. + Enthält Normalisierungen für JSON/CSV. + labels: autofix, ci + signoff: false + delete-branch: true diff --git a/.github/workflows/deploy-yoni-app.yml b/.github/workflows/deploy-yoni-app.yml new file mode 100644 index 0000000..c22a6ce --- /dev/null +++ b/.github/workflows/deploy-yoni-app.yml @@ -0,0 +1,37 @@ +name: Deploy YONI-app to Vercel + +on: + workflow_dispatch: # manueller 1-Click-Trigger + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install dependencies + run: npm install + + - name: Build project + run: npm run build + + # Optional: nur wenn du lint nutzen willst + # - name: Lint + # run: npm run lint + + - name: Deploy to Vercel + uses: vercel/vercel-action@v3 + with: + vercel-org-id: ${{ secrets.VERCEL_ORG_ID }} + vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }} + vercel-args: "--prod" + env: + VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..cc227ce --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,40 @@ +name: Deploy π⁷ Blueprint Kernel + +on: + push: + branches: + - main + - feature/pih7-blueprint-integration + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Lint + run: npm run lint + + - name: Build + run: npm run build + + - name: Deploy to Vercel (π⁷) + uses: vercel/vercel-action@v3 + with: + vercel-org-id: ${{ secrets.VERCEL_ORG_ID }} + vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }} + vercel-args: "--prod" + env: + VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..d6d7d1e --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,64 @@ +name: CI for YONI (x148) +# Trigger the workflow on pushes to `main` and PRs targeting `main`. +on: + push: + branches: + - main + - "releases/*" + pull_request: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + pull-requests: write + +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: "20" + + - name: Install dependencies + run: | + npm install + + - name: Run linter (if available) + run: | + if [ -f package.json ] && npm run | grep -q "lint"; then + npm run lint + else + echo "No lint script defined" + fi + + - name: Run tests (if available) + run: | + if [ -f package.json ] && npm test --help > /dev/null 2>&1; then + npm test + else + echo "No test script defined" + fi + + - name: Build project (if available) + run: | + if [ -f package.json ] && npm run | grep -q "build"; then + npm run build + else + echo "No build script defined" + fi + + - name: Upload build artifacts (optional) + uses: actions/upload-artifact@v4 + if: success() + with: + name: yoni-build-artifacts + path: | + build + dist diff --git a/.github/workflows/prod_smoke_tests.yml b/.github/workflows/prod_smoke_tests.yml new file mode 100644 index 0000000..cc15e63 --- /dev/null +++ b/.github/workflows/prod_smoke_tests.yml @@ -0,0 +1,116 @@ +name: 🔍 Production Smoke Tests + +on: + workflow_dispatch: + inputs: + prod_domain: + description: "Production domain (e.g., yoni-app.vercel.app)" + required: true + type: string + schedule: + # Run daily at 6:00 UTC + - cron: "0 6 * * *" + +permissions: + contents: read + +jobs: + smoke-tests: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Set Production Domain + id: set-domain + run: | + if [ -n "${{ github.event.inputs.prod_domain }}" ]; then + echo "PROD_DOMAIN=${{ github.event.inputs.prod_domain }}" >> $GITHUB_ENV + else + # Default domain if not provided (should be set in repository secrets) + echo "PROD_DOMAIN=${{ secrets.PROD_DOMAIN }}" >> $GITHUB_ENV + fi + + - name: Verify Production Domain + run: | + if [ -z "$PROD_DOMAIN" ]; then + echo "❌ Production domain not set. Please provide it via input or set PROD_DOMAIN secret." + exit 1 + fi + echo "✅ Testing production domain: $PROD_DOMAIN" + + - name: Install Vercel CLI (Optional) + run: npm install -g vercel + continue-on-error: true + + - name: List Vercel Deployments (Optional) + run: | + if command -v vercel &> /dev/null; then + vercel ls || echo "⚠️ Vercel ls failed (token may not be configured)" + else + echo "⚠️ Vercel CLI not available" + fi + env: + VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} + continue-on-error: true + + - name: Smoke Test - Stripe Webhook Endpoint + run: | + echo "🧪 Testing Stripe webhook endpoint..." + RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \ + -H "stripe-signature: invalid" \ + -d '{}' \ + "https://$PROD_DOMAIN/api/stripe/webhook") + + HTTP_CODE=$(echo "$RESPONSE" | tail -1) + BODY=$(echo "$RESPONSE" | head -n -1) + + echo "HTTP Status: $HTTP_CODE" + echo "Response: $BODY" + + # Expect 400 Bad Request for invalid signature + if [ "$HTTP_CODE" = "400" ]; then + echo "✅ Stripe webhook endpoint is working correctly (rejected invalid signature)" + else + echo "⚠️ Unexpected status code from Stripe webhook: $HTTP_CODE" + echo "Response body: $BODY" + fi + + - name: Smoke Test - GitHub App Webhook Endpoint + run: | + echo "🧪 Testing GitHub App webhook endpoint..." + + # Generate HMAC signature for the payload + PAYLOAD='{}' + SIG=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "${{ secrets.GITHUB_WEBHOOK_SECRET }}" -r | cut -d' ' -f1) + + RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \ + -H "x-github-event: ping" \ + -H "x-hub-signature-256: sha256=$SIG" \ + -H "content-type: application/json" \ + -d "$PAYLOAD" \ + "https://$PROD_DOMAIN/api/github-app/webhook") + + HTTP_CODE=$(echo "$RESPONSE" | tail -1) + BODY=$(echo "$RESPONSE" | head -n -1) + + echo "HTTP Status: $HTTP_CODE" + echo "Response: $BODY" + + # Expect 200 OK for valid signature + if [ "$HTTP_CODE" = "200" ]; then + echo "✅ GitHub App webhook endpoint is working correctly" + else + echo "⚠️ Unexpected status code from GitHub webhook: $HTTP_CODE" + echo "Response body: $BODY" + fi + + - name: Test Summary + if: always() + run: | + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "🏁 Production Smoke Tests Complete" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "Tested domain: $PROD_DOMAIN" + echo "Timestamp: $(date -u +"%Y-%m-%d %H:%M:%S UTC")" diff --git a/.github/workflows/repo-cleanup.yml b/.github/workflows/repo-cleanup.yml new file mode 100644 index 0000000..31c96fa --- /dev/null +++ b/.github/workflows/repo-cleanup.yml @@ -0,0 +1,78 @@ +name: Repo Cleanup +on: + workflow_dispatch: + inputs: + dry_run: + description: "Nur anzeigen, nicht löschen (true/false)" + required: false + default: "false" + +permissions: + contents: write # refs/heads/* löschen + pull-requests: write # PRs schließen + +jobs: + cleanup: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup gh + uses: cli/cli-action@v2 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + + - name: Close WIP PRs von Copilot + env: + REPO: pappensex/YONI-app + DRY_RUN: ${{ github.event.inputs.dry_run }} + run: | + set -euo pipefail + prs=$(gh pr list --repo "$REPO" --state open --search "author:Copilot in:title [WIP]" --json number --jq '.[].number') + echo "Offene WIP-PRs: $prs" + if [ "${DRY_RUN}" = "true" ]; then exit 0; fi + for n in $prs; do + gh pr close "$n" --repo "$REPO" --delete-branch=false + done + + - name: Lösche Branches mit Präfix copilot/ + env: + REPO: pappensex/YONI-app + DRY_RUN: ${{ github.event.inputs.dry_run }} + run: | + set -euo pipefail + # Liste aller Branches abrufen (paginiert) + page=1 + to_delete="" + while :; do + resp=$(gh api -X GET repos/$REPO/branches -F per_page=100 -F page=$page) + names=$(echo "$resp" | jq -r '.[].name') + [ -z "$names" ] && break + matches=$(echo "$names" | grep '^copilot/' || true) + to_delete="$to_delete"$'\n'"$matches" + page=$((page+1)) + done + to_delete=$(echo "$to_delete" | sed '/^$/d' || true) + echo "Kandidaten:" + echo "$to_delete" + if [ -z "$to_delete" ]; then exit 0; fi + if [ "${DRY_RUN}" = "true" ]; then exit 0; fi + # Refs löschen + while IFS= read -r br; do + echo "Lösche $br" + gh api -X DELETE "repos/$REPO/git/refs/heads/$br" || true + done <<< "$to_delete" + + - name: Merged-Branches aufräumen (optional) + if: ${{ github.event.inputs.dry_run != 'true' }} + env: + REPO: pappensex/YONI-app + run: | + set -euo pipefail + # alle remote-Branches, die in main gemerged sind und mit copilot/ beginnen + git fetch --prune + git branch -r --merged origin/main | sed 's# *origin/##' | grep '^copilot/' | while read br; do + echo "Prune $br" + gh api -X DELETE "repos/$REPO/git/refs/heads/$br" || true + done diff --git a/.github/workflows/validate-content.yml b/.github/workflows/validate-content.yml new file mode 100644 index 0000000..22a20f8 --- /dev/null +++ b/.github/workflows/validate-content.yml @@ -0,0 +1,17 @@ +name: Validate JSON & CSV +on: + pull_request: + paths: + - "project-ops/launch/**" + +jobs: + validate: + if: github.actor != 'github-actions[bot]' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: { node-version: "20" } + - run: npm ci --ignore-scripts --fund=false + - run: node scripts/validate-notion.js project-ops/launch/notion-template.json + - run: node scripts/validate-tasks-csv.js project-ops/launch/launch_tasks.csv diff --git a/.github/workflows/yoni-x148.2025-11-03.private-key.pem b/.github/workflows/yoni-x148.2025-11-03.private-key.pem new file mode 100644 index 0000000..cb5a4d5 --- /dev/null +++ b/.github/workflows/yoni-x148.2025-11-03.private-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEArlnJBWZ7Tig7sn+TwSC77TkYPNXwgPbL3v+fcW5/xyjQiPYI +ueCSAJlInG4nk8GG/ODyr+jJUWHObQgWhFOTiNzfx+mVhNZhDiK8WvfkmgiTth5t +DZbFEj0jbX4QFhXCTZ72j0l+pBIrKeDj22d9EzSVncIQreTQWlNA012UsP1OEjy2 +qaGpO+FuFGLFpG19men2FJ7+CSyKImSxGcQRenHKX80ITO6Uqdh4HOIKXlo16Dl6 +GRhxRwux+ANs5OivjWFpmCW4cNjagNByrVTS1PX+VmoDeWmhEkNJmMIDao2oNYCS +ha2OtsPcrBLmU6lxZnaCPctdu3deZtl243xE8wIDAQABAoIBAQCY8Al1wz/Gf2Re +X6qsbppqrPql4sTlW5faNUEXr2ZGvXavraJZ6rQn8k3PapEs+0X97RT1Wa2+xZzd +54pY6Tcxhw6FvlB6BdN9Its2sNzGgV+REX93vBmCtj6tfTd/J/cZP6foaP+9zHIw +eiVmAJGmlynnCKS45U4e7Yif4CbeWOG1yfmz2uLqEOrX8wxpc+EmfIoCZ6HwJ1qi +YO6HNgDMeKNGV1sRUG+E8NE0Qp/WyyYxNtyGDp05uXSpoR8P4Mw1iYSqzcecfuCr +1XyeAZo+W1T5pqlnGq1nwjCaCDnUPRozbiPV11bEmB1Eybal36Re8lu2puz86+SC +Hy/hJGKBAoGBANgPJ/2VPu15tEqcJEZMgpe2HNS7Ggr4w0BirtA/WD3XXrK6deSs +y7aGnJwKJoRPGHn90tR7rmkgfU2cibXZoHezD3Q4gazt43ElbxojSRLiFisWATpf +Pllk//HG39a0MiFXse+lZdqlFPw0ECq5s6Mdnv+KwcI0ThCdu1lnzq+NAoGBAM6U +zkJjKtfziQdbnHTQZkFUB5/AU0TlMU8e2TbQtgh+RIpvADVT/Yd5X4dDc0Id4qES +GaLZkg89CpZcYD182svPZLkTv8AVa0VmQQg5ryjmTz6sg7ROqXFrEu1jw3Losz35 +xWmlF9a26oEmio4TILlFrUiE/53Kc+VXq/bdRWZ/AoGACxjMLwQJVV0Y23QlkM7B +LlWWKX7qmYGpVZc770oxmAuFu5xEDdiqJdfIF2OWEtmVIj7dIziu/otCpEfT8tkY +ms1Bj/CPCHi3Y8pOaINDb4rZJKFessbNhv3e/2X9fSOIJ5o/c1WFY7Ny3nk2E1uy +VEBjODDCPt083TGcu7zPKskCgYBpI60ydpxYmpdUSlj/zw0sFKNouA7pUqjc9vtg +fasX+YPS3RnDCoNPjwOCqV6g+OreRYMMsiU3Yj7gNhW5VbFZ560A0T9XeM9G2/sf +P5SZgVY1tMG3ZA2zLubMMWlJM4v+b//8e8z9N810e/QqyStvgDnoXeBnI6IGyK86 +DnYC6wKBgQC3wcL91wHHYzrh5A9AkWUTY2oLaH1Z6n6NzHcDfRW3T4NQHIPPWNo8 +6bXGgw95SV+osJFyCgY8vyANp6EelRIyqtPyv6Q3KBp3C7aHUw0KIPgjYqxuf+K5 +MmPnJ2cmuDO5FRo8zjFiAQGXAp9o1xLHqsD8TPwtMd6RCdh8IXdsdA== +-----END RSA PRIVATE KEY----- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae13203 --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local +.env + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts +replace.txt diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..6621ea8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ +# Changelog + +## v0.9.0 +- Initial PI² app skeleton with landing page, dashboard, modules, API routes, Stripe skeleton, and legal pages. diff --git a/COMMIT_MESSAGE.txt b/COMMIT_MESSAGE.txt new file mode 100644 index 0000000..43dcf78 --- /dev/null +++ b/COMMIT_MESSAGE.txt @@ -0,0 +1,55 @@ +feat(ops): add Notion template and CI validation for launch management + +Introduce comprehensive launch task management infrastructure with Notion +integration and automated CI validation to support the YONI app launch. + +Files Added/Modified: + +Launch Task Management (project-ops/launch/): +- notion-template.json: Structured task template for three strategic pillars + (BUILD, PAYMENT, YOUTUBE) with 12 tasks, status tracking, and priorities +- tasks.csv: Flat CSV representation for external tool imports (Jira/Trello) +- README.md: Complete documentation with jq queries, CSV usage, and workflow + +Deploy Control Center (core/modules/deploy-center/): +- notionFormulas.ts: Notion-style formula utilities (prop, round, format, + toNumber, calculateSubtasksDone) for progress calculations +- notionFormulas.test.ts: Comprehensive test suite validating all formula + functions with real-world percentage calculation examples +- README.md: Formula documentation with step-by-step execution examples +- YoniDeployControlCenter.tsx: React component integrating Notion formulas + +CI/CD Infrastructure (.github/workflows/): +- main.yml: GitHub Actions workflow for automated build, test, and lint + validation on pushes and PRs targeting main branch + +Rationale: + +1. Task Management: Provides structured approach to YONI launch with clear + ownership across BUILD (technical), PAYMENT (monetization), and YOUTUBE + (marketing) pillars. JSON format enables programmatic access, CSV ensures + compatibility with existing project management tools. + +2. Notion Integration: Implements Notion formula syntax + (toNumber(format(round(prop())))) to maintain consistency between YONI + Deploy Control Center and external Notion workspace, enabling seamless + progress tracking across platforms. + +3. CI Validation: Establishes automated quality gates for all code changes, + running linter, tests, and build on every PR to prevent regressions and + ensure code quality standards are maintained throughout launch sprint. + +4. Documentation: Comprehensive README files provide quick-start guides, usage + examples, and integration patterns, reducing onboarding friction for new + contributors and ensuring knowledge continuity. + +Benefits: +- Single source of truth for launch tasks across all platforms +- Automated validation reduces manual review overhead +- Formula utilities enable consistent progress calculations +- Flexible export formats (JSON/CSV) support diverse workflows +- Clear documentation accelerates team collaboration + +BREAKING CHANGE: None - This is additive functionality only. + +Refs: #49 diff --git a/COMMIT_MESSAGES_README.md b/COMMIT_MESSAGES_README.md new file mode 100644 index 0000000..9d5057b --- /dev/null +++ b/COMMIT_MESSAGES_README.md @@ -0,0 +1,148 @@ +# Conventional Commit Messages for Notion Template & CI Validation + +This directory contains three versions of the Conventional Commit message +summarizing the addition of Notion template and CI validation features. + +## Files + +### 1. COMMIT_MESSAGE_OPTIMIZED.txt ⭐ (RECOMMENDED) + +**Best for:** Actual git commits and PR descriptions + +✓ Subject line: 49 characters (under 50) +✓ Body lines: max 69 characters (under 72) +✓ Follows Conventional Commits spec perfectly +✓ Comprehensive yet properly formatted + +```bash +# Use in git commit +git commit -F COMMIT_MESSAGE_OPTIMIZED.txt + +# Or copy for PR description +cat COMMIT_MESSAGE_OPTIMIZED.txt +``` + +### 2. COMMIT_MESSAGE_CONCISE.txt + +**Best for:** Quick summaries and short documentation + +- Compact version +- Same essential information +- Easier to scan quickly + +### 3. COMMIT_MESSAGE.txt + +**Best for:** Detailed documentation and reference + +- Most comprehensive +- Slightly longer lines +- Good for documentation files + +## Conventional Commits Format + +All messages follow the [Conventional Commits](https://www.conventionalcommits.org/) specification: + +``` +(): + + + +