From 6caefb420a29fab148608ce27f6389776cc1d1bc Mon Sep 17 00:00:00 2001 From: Unchained Date: Fri, 3 Apr 2026 21:06:15 +0200 Subject: [PATCH] docs: add OpenCode project memory for git workflow --- .opencode/PROJECT_MEMORY.md | 189 ++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 .opencode/PROJECT_MEMORY.md diff --git a/.opencode/PROJECT_MEMORY.md b/.opencode/PROJECT_MEMORY.md new file mode 100644 index 0000000..56c91f2 --- /dev/null +++ b/.opencode/PROJECT_MEMORY.md @@ -0,0 +1,189 @@ +# ManoonOils Project Memory + +## Project Overview +- **Name:** ManoonOils Headless Storefront +- **Type:** Next.js 16 + Saleor e-commerce +- **URL:** https://manoonoils.com +- **Tech Stack:** React 19, TypeScript, Tailwind CSS v4, GraphQL/Apollo + +## Git Workflow (CRITICAL) + +``` +feature/* → dev → master +``` + +### Rules (MUST FOLLOW) +1. **All work starts on feature branch** - Never commit to dev/master directly +2. **Commit working code immediately** - No uncommitted files in working directory +3. **Clean working directory before switching branches** - Run `git status` first +4. **Flow forward only** - feature → dev → master, never skip +5. **Reset feature branches after merge** - Keep synchronized with master + +### Workflow Steps +```bash +# 1. Create feature branch +git checkout -b feature/description + +# 2. Work and commit WORKING code +git add . +git commit -m "type: description" +git push origin feature/description + +# 3. Merge to dev for testing +git checkout dev +git merge feature/description +git push origin dev + +# 4. Merge to master for production +git checkout master +git merge dev +git push origin master + +# 5. Reset feature branch to match master +git checkout feature/description +git reset --hard master +git push origin feature/description --force +``` + +### Commit Types +- `feat:` - New feature +- `fix:` - Bug fix +- `docs:` - Documentation +- `style:` - Formatting +- `refactor:` - Code restructuring +- `test:` - Tests +- `chore:` - Build/process + +## Project Structure + +### Key Directories +``` +src/ +├── app/[locale]/ # i18n routes +├── components/ +│ ├── home/ # Homepage sections +│ ├── layout/ # Header, Footer +│ ├── providers/ # Context providers +│ └── ui/ # Reusable UI +├── hooks/ # Custom hooks +├── lib/ +│ ├── mautic.ts # Mautic API client +│ ├── geoip.ts # GeoIP service +│ └── analytics.ts # Analytics tracking +├── i18n/messages/ # Translations (sr, en, de, fr) +k8s/ # Kubernetes manifests +``` + +### Important Files +- `k8s/deployment.yaml` - Production deployment config +- `src/app/[locale]/layout.tsx` - Root layout with ExitIntentDetector +- `src/lib/mautic.ts` - Mautic integration +- `.env.local` - Environment variables + +## Environment Variables + +### Required for Production +```bash +# Saleor +NEXT_PUBLIC_SALEOR_API_URL=https://api.manoonoils.com/graphql/ + +# Mautic +MAUTIC_CLIENT_ID=2_23cgmaqef8kgg8oo4kggc0w4wccwoss8o8w48o8sc40cowgkkg +MAUTIC_CLIENT_SECRET=4k8367ab306co48c4c8g8sco8cgcwwww044gwccs0o0c8w4gco +MAUTIC_API_URL=https://mautic.nodecrew.me + +# Analytics +NEXT_PUBLIC_RYBBIT_HOST=https://rybbit.nodecrew.me +NEXT_PUBLIC_RYBBIT_SITE_ID=1 +RYBBIT_API_KEY=... + +# Email +RESEND_API_KEY=... +``` + +## Current Features + +### Email Capture Popup +- **Location:** `src/components/home/EmailCapturePopup.tsx` +- **Trigger:** `src/components/home/ExitIntentDetector.tsx` +- **Triggers:** Scroll 10% OR exit intent (mouse leaving viewport) +- **Delay:** Scroll has 5s delay, exit intent shows immediately +- **Fields:** First name (optional), Email (required) +- **Tracking:** UTM params, device info, time on page, referrer +- **Integration:** Creates contact in Mautic with tags + +### API Routes +- `/api/email-capture` - Handles form submission to Mautic +- `/api/geoip` - Returns country/region from IP + +### i18n Support +- **Locales:** sr (default), en, de, fr +- **Translation files:** `src/i18n/messages/*.json` + +## Common Commands + +### Development +```bash +npm run dev # Start dev server +npm run build # Production build +npm run test # Run tests +``` + +### Kubernetes (doorwaysftw server) +```bash +# Check pods +ssh doorwaysftw "kubectl get pods -n manoonoils" + +# Restart storefront +ssh doorwaysftw "kubectl delete pod -n manoonoils -l app=storefront" + +# Check logs +ssh doorwaysftw "kubectl logs -n manoonoils deployment/storefront" + +# Verify env vars +ssh doorwaysftw "kubectl exec -n manoonoils deployment/storefront -- env | grep MAUTIC" +``` + +## Known Issues & Solutions + +### Hydration Errors +- **Cause:** `AnalyticsProvider` returning `null` +- **Solution:** Return `<>` instead, or remove component + +### Popup Not Showing +- Check `ExitIntentDetector` is in `layout.tsx` +- Verify `useVisitorStore` isn't showing popup already shown +- Check browser console for errors + +### Mautic API Failures +- Verify env vars in k8s deployment +- Check Mautic credentials haven't expired +- Ensure country code isn't "Local" (use "XX" instead) + +## Deployment Checklist + +Before deploying to production: +- [ ] All tests pass (`npm run test`) +- [ ] Build succeeds (`npm run build`) +- [ ] No uncommitted changes (`git status`) +- [ ] Merged to dev and tested +- [ ] Merged to master +- [ ] K8s deployment.yaml has correct env vars +- [ ] Pod restarted to pick up new code +- [ ] Smoke test on production URL + +## Architecture Decisions + +### Why No AnalyticsProvider? +Removed because it returns `null` causing hydration mismatches. Analytics scripts loaded directly in layout. + +### Why Direct Rybbit URL? +Using `https://rybbit.nodecrew.me/api/script.js` instead of `/api/script.js` preserves real visitor IP. + +### Why Exit Intent + Scroll? +Exit intent catches leaving users immediately. Scroll trigger catches engaged users after delay. + +## Contact +- **Maintainer:** User +- **K8s Server:** doorwaysftw (100.109.29.45) +- **Mautic:** https://mautic.nodecrew.me