# miniSISKA — Git Workflow & Developer Guide

Complete reference for version control, backup, rollback, and safe Claude development.

---

## Safe Auto-Backup System (v2 — May 2026)

### Two Ways to Backup

**In-App (Recommended):** Click **🛠 Dev** → **Backup to GitHub Now**
- Security scan runs first
- Only safe source files staged
- Auto-timestamped commit
- Logs to `logs/git-backup.log`

**Desktop script:** Double-click `git-safe-backup.bat`

### Security Scan Blocks These
| Pattern | Reason |
|---------|--------|
| `.env` not in `.gitignore` | Secrets would leak |
| `.env` tracked by git | Immediate block |
| `sk-proj-...` (60+ chars) | OpenAI key |
| `EAAM...` (60+ chars) | Meta token |
| `Bearer ...` (40+ chars) | Raw bearer token |
| `logs/` staged | Runtime logs |
| `storage/uploads/` staged | User media |

### What Gets Committed
Only explicit safe paths: `api/`, `config/`, `public/`, `social/`, `prompts/`, `cron/`, `database/`, `docs/`, `.gitignore`, `.htaccess`, batch files.

### Verify Backup Worked
1. App shows `✓ Backup Complete`
2. Check `logs/git-backup.log` for `SUCCESS`
3. Visit GitHub repo → latest commit matches timestamp

---

---

## Daily Workflow

### After a successful update, always backup:

**Option 1 — Double-click (Windows):**
```
git-backup.bat
```

**Option 2 — PowerShell:**
```powershell
.\git-backup.ps1
```

**Option 3 — Manual (Git Bash / PowerShell):**
```bash
git status
git add .
git commit -m "miniSISKA update - [describe what changed]"
git push origin main
```

---

## Commit Message Convention

Format: `miniSISKA update - [module/feature]`

Examples:
```
miniSISKA update - Threads engine 9 modes
miniSISKA update - Structured content output system
miniSISKA update - Video upload ffmpeg conversion
miniSISKA update - AI media analysis fix
miniSISKA update - Token auto-renewal cron
miniSISKA update - Facebook posting integration
miniSISKA update - Scheduler improvements
miniSISKA update - Dashboard analytics
miniSISKA update - Developer tools panel
miniSISKA update - Security and .gitignore fix
```

---

## Checking Current Status

```bash
# See what files changed since last commit
git status

# See the actual code differences
git diff

# See only staged changes (ready to commit)
git diff --staged

# See recent commits
git log --oneline -10

# See full log with dates
git log --pretty=format:"%h %ad %s" --date=short -20
```

---

## Safe Backup (Before Any Major Change)

Before Claude makes large edits to a working module, create a tagged checkpoint:

```bash
# Tag current working state
git tag -a v2.6-stable -m "Stable before structured content system"

# Push the tag to GitHub
git push origin v2.6-stable

# List all tags
git tag -l
```

---

## Rollback — Restore Previous Version

### Undo last commit (keep file changes — safest)
```bash
git reset --soft HEAD~1
```

### Undo last commit (discard file changes — destructive)
```bash
git reset --hard HEAD~1
```

### Restore a single file to its last committed version
```bash
git checkout HEAD -- api/openai.php
git checkout HEAD -- public/index.php
```

### Restore a file from 3 commits ago
```bash
git checkout HEAD~3 -- api/openai.php
```

### Go back to a specific commit (view only — safe)
```bash
git checkout abc1234
# Go back to current state
git checkout main
```

### Full rollback to a specific commit (destructive — creates new branch first!)
```bash
git checkout -b rollback-2026-05-14
git reset --hard abc1234
git push origin rollback-2026-05-14
```

---

## Restore Deleted File

```bash
# Find the commit where the file last existed
git log --all --full-history -- path/to/deleted-file.php

# Restore it from that commit
git checkout [commit-hash] -- path/to/deleted-file.php

# Stage and commit the restore
git add path/to/deleted-file.php
git commit -m "miniSISKA restore - deleted file recovery"
```

---

## Restore Previous Stable Version (Full App Reset)

```bash
# 1. Find the good commit
git log --oneline -20

# 2. Create a backup branch of current broken state
git checkout -b backup-broken-$(date +%Y%m%d)

# 3. Return to main
git checkout main

# 4. Reset main to the known-good commit
git reset --hard [good-commit-hash]

# 5. Force push (only if you are the only user — private repo)
git push --force origin main
```

---

## What Is NEVER Pushed to GitHub

The `.gitignore` enforces these rules automatically. Never bypass it.

| Excluded | Reason |
|----------|--------|
| `.env` | Contains API keys, DB password |
| `logs/` | Runtime logs — can contain token data |
| `storage/uploads/` | User media files — large, private |
| `backups/database/*.sql` | DB dumps may contain user data |
| `backups/media/` | Large binary files |
| `cache/` | Generated temp files |
| `*.sess` | PHP session files |
| `vendor/` | Composer packages (install from composer.json) |
| `node_modules/` | NPM packages (if added later) |

---

## Checking What Git Would Push

```bash
# See all files tracked by git (should NOT see .env or uploads)
git ls-files

# Verify .env is NOT tracked
git ls-files | grep ".env"
# Expected: no output

# Verify uploads are NOT tracked
git ls-files | grep "storage/uploads"
# Expected: only .htaccess and .gitkeep
```

---

## Pre-Push Safety Checklist

Before `git push`, verify:

- [ ] `.env` is NOT in `git status`
- [ ] No API keys in any committed file (`git grep "sk-"` returns nothing)
- [ ] No access tokens visible (`git grep "EAAIE"` returns nothing)
- [ ] `storage/uploads/` shows only `.htaccess` and `.gitkeep`
- [ ] `backups/` shows only `.gitkeep` files
- [ ] `logs/` is not tracked (`git ls-files logs/` returns nothing)

---

## Claude Development Safety Rules

When working with Claude on large changes:

1. **Always commit current working state first** — before asking Claude to refactor
2. **Use tagged commits** for stable versions before major features
3. **Review `git diff` before committing** — Claude may touch more files than intended
4. **Never ask Claude to `git push --force` on main** — create a branch instead
5. **Test in browser before committing** — verify the generated/modified page works
6. **One feature per commit** — easier to rollback a single broken feature

### Modules Claude Must Not Break
These are production-critical and must be preserved:
- `api/openai.php` — AI generation core
- `social/threads.php` — Threads posting + token renewal
- `social/meta.php` — Facebook/Instagram posting
- `social/telegram.php` — Telegram posting
- `cron/post_scheduler.php` — Scheduler
- `cron/refresh_tokens.php` — Token auto-renewal
- `public/index.php` — Main UI
- `config/env.php` — Env loader (breaking this breaks everything)
- `config/database.php` — DB connection

---

## Database Backup (Before Migrations)

Export via phpMyAdmin, OR via command line:

```bash
# Export (from XAMPP shell or Git Bash)
"C:\xampp\mysql\bin\mysqldump.exe" -u root mini_siska > backups/database/mini_siska_2026-05-14.sql

# Import (restore)
"C:\xampp\mysql\bin\mysql.exe" -u root mini_siska < backups/database/mini_siska_2026-05-14.sql
```

These `.sql` files are gitignored — they stay local only.

---

## GitHub Private Repo Setup

```bash
# Initial push to new private repo
git remote add origin https://github.com/YOUR-USERNAME/mini-siska.git
git branch -M main
git push -u origin main

# Subsequent pushes
git push origin main

# Pull latest from GitHub (if editing on another machine)
git pull origin main
```

---

## Branching Strategy (When Needed)

```bash
# Create a feature branch for risky changes
git checkout -b feature/tiktok-integration

# Work on the feature...
git add .
git commit -m "miniSISKA update - TikTok API integration WIP"

# Merge back to main when stable
git checkout main
git merge feature/tiktok-integration

# Delete the feature branch
git branch -d feature/tiktok-integration
```

---

## Emergency: File Accidentally Committed with Secret

If a secret is committed:

1. Rotate the key immediately (OpenAI dashboard, Meta developer portal)
2. Remove from history:
   ```bash
   git filter-branch --force --index-filter \
     'git rm --cached --ignore-unmatch .env' \
     --prune-empty --tag-name-filter cat -- --all
   git push --force origin main
   ```
3. Verify with `git log --all -- .env` — should be empty after filter
4. Update `.gitignore` to prevent recurrence
