# Punjabi Mandi — Master Implementation Plan (Final)

## Codebase Analysis Summary

| Aspect | Current State |
|--------|---------------|
| **Laravel Version** | 11.22.0 (installed via `laravel/framework: ^11.9`) |
| **PHP Version** | 8.2.0 (ZTS, Laragon) |
| **Target Laravel** | 13.x (latest stable, requires PHP ≥ 8.3) |
| **Frontend Stack** | Bootstrap 5 + jQuery + OwlCarousel + Blade + Vue 3 + Vite 5 |
| **Payment Gateway** | Authorize.Net (SANDBOX — keep during development) |
| **Auth System** | Multi-guard: `web` (User), `admin` (Admin), `customer` (Customer) |
| **Database** | MySQL (`punjabimandi`) via Laragon |
| **Old Platform** | Bagisto e-commerce (119 tables in `wwwpunjabimandi_app_old.sql`) |
| **Old Images Path** | `E:\TAS\punjabimandi\storage\app\public` (product, category, slider_images, etc.) |
| **Models** | 44 Eloquent models covering Product, Category, Cart, Order, Customer, etc. |
| **Architecture** | MVC with `Kernel.php`, `config/app.php` providers, `MiddlewareServiceProvider` |

### Key Architectural Observations

- Uses **Laravel 10-style** `Kernel.php` + `RouteServiceProvider` + `config/app.php` providers array (not the Laravel 11+ `bootstrap/app.php` style)
- Has a custom `CustomerEmailIsVerified` middleware and `MiddlewareServiceProvider` that duplicates Kernel middleware aliases
- Uses `staudenmeir/laravel-adjacency-list` for category tree (recursive relationships)
- `Punjabi.php` helper serves as the central settings/utility class (aliased as `Punjabi` facade)
- Product images stored in `storage/app/public` with symlink to `public/storage`
- Old Bagisto DB uses a normalized EAV pattern (`product_flat`, `product_attribute_values`, `category_translations`)

---

## Resolved Questions Summary

| # | Question | Answer |
|---|----------|--------|
| 1 | Migrate old customers/orders? | **No** — only product catalog data (categories, products, images, inventory) |
| 2 | Authorize.Net environment? | **Keep SANDBOX** during development |
| 3 | Which AI API keys? | **Groq** (primary), **OpenRouter** (1st fallback), **Cloudflare Workers AI** (2nd fallback). No Gemini needed. |
| 4 | Domain/DNS help? | **Yes** — need server/DNS configuration guidance |
| 5 | Mail from address? | **Yes** — change to `noreply@punjabimandi.com` |
| 6 | Brands in old DB? | **No brands table** in old Bagisto DB — skip brand migration |

---

## Proposed Changes

The work is organized into 5 tasks, executed sequentially with testing after each.

---

### Task 1: Laravel Version Upgrade (11 → 12 → 13)

This is the foundational task. Everything else depends on a stable, upgraded framework.

#### Phase 1A: PHP 8.3 Upgrade in Laragon

> [!IMPORTANT]
> Laravel 13 requires PHP ≥ 8.3. Your current Laragon has PHP 8.2.0. This must be upgraded first.

- Download PHP 8.3.x (Thread Safe) from https://windows.php.net/download
- Place in `C:\laragon\bin\php\php-8.3.x-ts-vs16-x64`
- Switch Laragon to use PHP 8.3 via Menu → PHP → select 8.3
- Verify all required extensions: `pdo_mysql`, `mbstring`, `openssl`, `curl`, `xml`, `zip`, `fileinfo`, `bcmath`
- Confirm `php -v` reports 8.3+

#### Phase 1B: Laravel 11 → 12 Upgrade

##### [MODIFY] [composer.json](file:///c:/laragon/www/punjabimandi/composer.json)
- Update `laravel/framework` to `^12.0`
- Update `laravel/sanctum` to `^5.0`
- Update `laravel/tinker` to `^3.0`
- Update `phpunit/phpunit` to `^12.0`
- Update `nunomaduro/collision` to `^9.0`
- Update `laravel/pint` to `^2.0`
- Update `laravel/sail` to `^2.0`
- Verify `staudenmeir/laravel-adjacency-list` compatibility (update if needed)

##### [MODIFY] [config/app.php](file:///c:/laragon/www/punjabimandi/config/app.php)
- Review for deprecated `ServiceProvider::defaultProviders()` pattern
- Migrate providers to `bootstrap/app.php` if Laravel 12 requires it

##### [MODIFY] [app/Http/Kernel.php](file:///c:/laragon/www/punjabimandi/app/Http/Kernel.php)
- If Laravel 12 removes `Kernel.php`, migrate middleware to `bootstrap/app.php`
- Review `VerifyCsrfToken` → `PreventRequestForgery` rename

##### Middleware Files (review each)
- [Authenticate.php](file:///c:/laragon/www/punjabimandi/app/Http/Middleware/Authenticate.php)
- [RedirectIfAuthenticated.php](file:///c:/laragon/www/punjabimandi/app/Http/Middleware/RedirectIfAuthenticated.php)
- [CustomerEmailIsVerified.php](file:///c:/laragon/www/punjabimandi/app/Http/Middleware/CustomerEmailIsVerified.php)
- [ValidateSignature.php](file:///c:/laragon/www/punjabimandi/app/Http/Middleware/ValidateSignature.php)
- Remove deprecated middleware classes (`EncryptCookies`, `TrimStrings`, `TrustProxies`, `PreventRequestsDuringMaintenance`, `VerifyCsrfToken`)

##### [MODIFY] Service Providers
- [MiddlewareServiceProvider.php](file:///c:/laragon/www/punjabimandi/app/Providers/MiddlewareServiceProvider.php) — may become redundant with `bootstrap/app.php`
- [RouteServiceProvider.php](file:///c:/laragon/www/punjabimandi/app/Providers/RouteServiceProvider.php) — review for deprecation
- [AuthServiceProvider.php](file:///c:/laragon/www/punjabimandi/app/Providers/AuthServiceProvider.php) — review
- [EventServiceProvider.php](file:///c:/laragon/www/punjabimandi/app/Providers/EventServiceProvider.php) — review

#### Phase 1C: Laravel 12 → 13 Upgrade

##### [MODIFY] [composer.json](file:///c:/laragon/www/punjabimandi/composer.json)
- Update `laravel/framework` to `^13.0`
- Update all other dependencies as required by Laravel 13
- Run `composer update`

##### [MODIFY] [.env](file:///c:/laragon/www/punjabimandi/.env)
- Explicitly set `CACHE_PREFIX`, `REDIS_PREFIX`, `SESSION_COOKIE` per Laravel 13 guidance
- Review any changed default values

##### Post-Upgrade Cleanup
- `php artisan config:clear && php artisan cache:clear && php artisan view:clear && php artisan route:clear`
- `php artisan migrate` to apply any new framework migrations
- Verify `php artisan serve` starts without errors
- Run existing tests

#### Verification — Task 1
```bash
php artisan --version   # Should show Laravel Framework 13.x.x
php -v                  # Should show PHP 8.3.x
php artisan test        # All tests pass
php artisan route:list  # No errors
```

---

### Task 2: Data Migration from Old Bagisto Database

> [!NOTE]
> **Scope confirmed**: Only product catalog data — categories, products, images, inventory. NO customers, orders, or brands.

#### Phase 2A: Database Connection Setup

##### [MODIFY] [config/database.php](file:///c:/laragon/www/punjabimandi/config/database.php)
- Add `old_mysql` connection pointing to the imported old database

##### [MODIFY] [.env](file:///c:/laragon/www/punjabimandi/.env)
```
OLD_DB_DATABASE=wwwpunjabimandi_app_old
```

#### Phase 2B: Migration Tracking

##### [NEW] `database/migrations/xxxx_create_data_migration_tracking_table.php`
- `data_migrations` table: `id`, `entity_type`, `old_id`, `new_id`, `status`, `error_message`, `created_at`
- Ensures idempotency — can re-run migration safely

#### Phase 2C: Cleanup Existing Demo Data

##### [NEW] `app/Console/Commands/CleanExistingData.php`
Artisan command `php artisan data:clean-existing` that:
1. Removes existing categories, products, product_images, product_categories, product_inventories from the new database
2. Removes corresponding images from `storage/app/public/`
3. Requires `--force` flag to prevent accidental execution

#### Phase 2D: Main Migration Command

##### [NEW] `app/Console/Commands/MigrateOldData.php`
Artisan command `php artisan migrate:old-data` that:

1. **Connects** to `old_mysql` (the Bagisto database)
2. **Migrates Categories**:
   - Reads `categories` + `category_translations` (for names, slugs, descriptions)
   - Maps `parent_id` relationships to new `categories` table
   - Copies category images from `E:\TAS\punjabimandi\storage\app\public\category\{id}\` to `storage/app/public/categories/`
   - Creates corresponding `images` records (polymorphic)
3. **Migrates Products**:
   - Reads `product_flat` table (denormalized: name, sku, url_key, price, special_price, description, status, weight, etc.)
   - Maps to new `products` table fields
   - Creates `product_categories` pivot records from old `product_categories` table
   - Copies product images from `E:\TAS\punjabimandi\storage\app\public\product\{product_id}\*.jpg/png/webp` to `storage/app/public/products/`
   - Creates `product_images` records with updated paths
   - Creates `product_inventories` records from old `product_inventories` table
4. **Supports flags**: `--dry-run` (preview), `--limit=N` (test with N records), `--skip-images` (faster testing)
5. **Generates a migration report** with success/failure/skipped counts

#### Phase 2E: Storage Symlink Verification
```bash
php artisan storage:link  # Ensure public/storage symlink exists
```

#### Verification — Task 2
```bash
php artisan data:clean-existing --force   # Clean existing demo data
php artisan migrate:old-data --dry-run    # Preview what will be migrated
php artisan migrate:old-data              # Run the migration
php artisan test --filter=DataMigration   # Run migration validation tests
```

##### [NEW] Tests
- `tests/Feature/DataMigration/CategoryMigrationTest.php` — Verify categories with parent/child relationships
- `tests/Feature/DataMigration/ProductMigrationTest.php` — Verify products with images, inventory, categories
- `tests/Feature/DataMigration/ImageMigrationTest.php` — Verify images copied and accessible

---

### Task 3: Rebranding — "Indian Punjabi Bazaar" → "Punjabi Mandi"

#### Phase 3A: Core Configuration Changes

##### [MODIFY] [.env](file:///c:/laragon/www/punjabimandi/.env)
```diff
-APP_NAME="Indian Punjabi Bazaar"
+APP_NAME="Punjabi Mandi"

-APP_URL=http://punjabimandi.test/
+APP_URL=https://punjabimandi.com

-MAIL_FROM_ADDRESS=noreply@ipbgrocery.com
+MAIL_FROM_ADDRESS=noreply@punjabimandi.com

-GOOGLE_REDIRECT_URL="https://ipbgrocery.com/beta/public/auth/google/callback"
+GOOGLE_REDIRECT_URL="https://punjabimandi.com/auth/google/callback"
```

##### [MODIFY] [database/seeders/SettingSeeder.php](file:///c:/laragon/www/punjabimandi/database/seeders/SettingSeeder.php)
- Update site name to "Punjabi Mandi"

#### Phase 3B: Frontend Brand Updates (Source Files Only — Cached Views Auto-Regenerate)

##### [MODIFY] [resources/views/frontend/layouts/master.blade.php](file:///c:/laragon/www/punjabimandi/resources/views/frontend/layouts/master.blade.php)
- Change `<title> Indian Punjabi Bazaar |` to `<title>Punjabi Mandi |`
- Update favicon path to new logo

##### [MODIFY] [resources/views/frontend/layouts/header.blade.php](file:///c:/laragon/www/punjabimandi/resources/views/frontend/layouts/header.blade.php)
- Replace logo image with new Punjabi Mandi logo
- Update any hardcoded brand text

##### [MODIFY] [resources/views/frontend/layouts/footer.blade.php](file:///c:/laragon/www/punjabimandi/resources/views/frontend/layouts/footer.blade.php)
- Replace all "Indian Punjabi Bazaar" text

##### [MODIFY] [resources/views/admin/layouts/master.blade.php](file:///c:/laragon/www/punjabimandi/resources/views/admin/layouts/master.blade.php)
- Update admin panel branding

##### [MODIFY] [resources/views/admin/auth/layouts/app.blade.php](file:///c:/laragon/www/punjabimandi/resources/views/admin/auth/layouts/app.blade.php)
- Update admin login page branding

##### [MODIFY] [resources/views/mail/customer-verify.blade.php](file:///c:/laragon/www/punjabimandi/resources/views/mail/customer-verify.blade.php)
- Update email template branding

##### [MODIFY] [app/Http/Controllers/Frontend/ShopController.php](file:///c:/laragon/www/punjabimandi/app/Http/Controllers/Frontend/ShopController.php)
- Line 79: `' Indian Punjabi Bazaar'` → `'Punjabi Mandi'`

#### Phase 3C: Logo & Favicon Update

##### [NEW] `public/frontend/assets/logo.png`
- Save the provided new logo (Punjabi Mandi green cart design)

##### [NEW] `public/frontend/assets/favicon.ico`
- Generated from new logo

##### Update all logo references in header, footer, admin views

#### Phase 3D: Domain & Server/DNS Configuration Guide

##### [NEW] `docs/dns-setup-guide.md`
A step-by-step guide for configuring `punjabimandi.com`:
- DNS A/CNAME records pointing to hosting server
- SSL certificate setup (Let's Encrypt / hosting panel)
- Apache/Nginx virtual host configuration
- Google OAuth redirect URL update in Google Console
- Brevo/SMTP domain verification for `punjabimandi.com`

#### Phase 3E: Cleanup
```bash
php artisan view:clear    # Remove all cached views with old branding
php artisan cache:clear   # Clear application cache
php artisan config:clear  # Clear config cache
```

#### Verification — Task 3
```bash
php artisan test --filter=Rebranding
# Automated scan for any remaining "Indian Punjabi Bazaar" or "ipbgrocery" in source files
```

##### [NEW] Tests
- `tests/Feature/Rebranding/BrandNameTest.php` — Verify no old brand name in key responses (home, footer, admin)
- `tests/Feature/Rebranding/LogoTest.php` — Verify new logo assets are accessible via HTTP

---

### Task 4: Frontend UI Update (Deferred — Awaiting Design)

> [!NOTE]
> You mentioned the new frontend UI design will be provided in 3-4 days. This task will be planned in detail once the design is received.

#### Anticipated Scope
- Redesign homepage layout
- Update product listing pages
- Modernize product detail pages
- Refresh cart and checkout flows
- Responsive mobile optimization
- Performance improvements (lazy loading, optimized images)

#### Technical Approach (Planned)
- Keep Bootstrap 5 + jQuery + OwlCarousel stack unless new design requires changes
- Update CSS in `public/frontend/assets/style.css`
- Modify Blade templates in `resources/views/frontend/`
- Potentially update Vite build pipeline

---

### Task 5: AI-Powered "Cook & Auto-Fill Cart" Feature

This is the most complex feature, implemented as a clean, isolated module.

#### Phase 5A: Configuration & Infrastructure

##### [NEW] `config/ai.php`
```php
return [
    'default_provider' => env('AI_PROVIDER', 'groq'),
    'fallback_chain' => ['openrouter', 'cloudflare'], // ordered fallbacks
    'providers' => [
        'groq' => [
            'api_key' => env('GROQ_API_KEY'),
            'model' => env('GROQ_MODEL', 'llama-3.3-70b-versatile'),
            'base_url' => 'https://api.groq.com/openai/v1',
        ],
        'openrouter' => [
            'api_key' => env('OPENROUTER_API_KEY'),
            'model' => env('OPENROUTER_MODEL', 'meta-llama/llama-3.3-70b-instruct:free'),
            'base_url' => 'https://openrouter.ai/api/v1',
        ],
        'cloudflare' => [
            'api_key' => env('CF_AI_API_KEY'),
            'account_id' => env('CF_ACCOUNT_ID'),
            'model' => env('CF_AI_MODEL', '@cf/meta/llama-3.3-70b-instruct-fp8-fast'),
        ],
    ],
    'cache_ttl' => env('AI_CACHE_TTL', 3600),
    'rate_limit' => [
        'max_requests_per_minute' => env('AI_RATE_LIMIT', 10),
    ],
];
```

##### [MODIFY] [.env](file:///c:/laragon/www/punjabimandi/.env)
```
# AI Cook & Auto-Fill Cart
AI_PROVIDER=groq
GROQ_API_KEY=
OPENROUTER_API_KEY=
CF_AI_API_KEY=
CF_ACCOUNT_ID=
AI_CACHE_TTL=3600
AI_RATE_LIMIT=10
```

#### Phase 5B: Service Layer (Backend)

##### [NEW] `app/Services/AI/Contracts/AIProviderInterface.php`
```php
interface AIProviderInterface
{
    public function parseRecipe(string $recipeName, int $servings = 4): array;
    public function isAvailable(): bool;
    public function getProviderName(): string;
}
```

##### [NEW] `app/Services/AI/AIManager.php`
- Factory/manager that resolves the configured provider (Groq primary)
- Implements **automatic fallback chain**: Groq → OpenRouter → Cloudflare
- Falls back when primary hits rate limit, returns errors, or times out
- Uses Laravel HTTP Client for all API calls
- Integrates with Laravel rate limiting (`RateLimiter` facade)
- Caches successful LLM responses keyed by `recipe_name:servings` hash

##### [NEW] `app/Services/AI/Providers/GroqProvider.php` (Primary)
##### [NEW] `app/Services/AI/Providers/OpenRouterProvider.php` (1st Fallback)
##### [NEW] `app/Services/AI/Providers/CloudflareProvider.php` (2nd Fallback)

Each provider:
- Implements `AIProviderInterface`
- Sends a carefully crafted prompt requesting structured JSON output
- Validates and parses the JSON response
- Handles provider-specific error codes and rate limits (HTTP 429, etc.)

##### [NEW] `app/Services/AI/IngredientNormalizer.php`
- Normalizes ingredient names from LLM output (e.g., "Channa Dal" → "Chana Dal", "Coriander Powder" → "Dhania Powder")
- Maintains a curated aliases mapping table
- Handles unit normalization (e.g., "250g" → 250 grams, "1 tbsp" → 15ml)

##### [NEW] `app/Services/AI/ProductMatcher.php`
- Matches normalized ingredient names against the `products` table
- Multi-tier matching strategy:
  1. **Exact match** on product name (case-insensitive)
  2. **Alias lookup** from curated `ingredient_aliases` table
  3. **Full-text search** using MySQL FULLTEXT index on product name/description
  4. **Fuzzy match** using `LIKE` with wildcards + Levenshtein distance scoring
- Returns match confidence: `exact`, `high`, `medium`, `low`, `not_found`
- **Always** fetches product_id, price, stock, inventory from the **database** (never from LLM)

##### [NEW] `app/Services/AI/QuantityConversionService.php`
- Converts recipe quantities (e.g., "2 cups", "500g", "1 bunch") to product purchase quantities
- Considers product weight/unit information from the database
- Returns suggested quantity to add to cart

##### [NEW] `database/migrations/xxxx_create_ingredient_aliases_table.php`
```
ingredient_aliases: id, ingredient_name, product_id, alias_variations (JSON), created_at, updated_at
```

##### [NEW] `database/seeders/IngredientAliasSeeder.php`
- Seeds common South Asian ingredient aliases (Haldi → Turmeric Powder, Jeera → Cumin Seeds, Rai → Mustard Seeds, etc.)

#### Phase 5C: Controller & Routes

##### [NEW] `app/Http/Controllers/Frontend/RecipeController.php`
```php
class RecipeController extends Controller
{
    public function parseRecipe(Request $request)    // POST /recipe/parse
    public function addToCart(Request $request)       // POST /recipe/add-to-cart
}
```

##### [MODIFY] [routes/web.php](file:///c:/laragon/www/punjabimandi/routes/web.php)
```php
// Cook & Auto-Fill Cart
Route::post('recipe/parse', [RecipeController::class, 'parseRecipe'])->name('recipe.parse');
Route::post('recipe/add-to-cart', [RecipeController::class, 'addToCart'])->name('recipe.add-to-cart');
```

#### Phase 5D: Frontend UI

##### [NEW] `resources/views/frontend/pages/sections/recipe-modal.blade.php`
A review modal showing:
- Recipe name & servings (editable)
- Matched ingredients table with:
  - Ingredient name (from recipe)
  - Matched product name (from database) with link
  - Match confidence indicator (✅ exact / 🟡 high / 🟠 medium / ❌ not found)
  - Quantity & unit
  - Unit price (from database)
  - Line total
  - Remove / adjust quantity buttons
- Estimated total
- "Add All to Cart" button
- Loading skeleton state
- Error/empty state

##### [MODIFY] [resources/views/frontend/layouts/header.blade.php](file:///c:/laragon/www/punjabimandi/resources/views/frontend/layouts/header.blade.php)
- Add a "🍳 Cook & Shop" button in the navigation/search area

##### [NEW] `public/frontend/assets/js/recipe.js`
- Recipe input UI, AJAX calls to `/recipe/parse`, modal rendering
- Handles loading states, error states, quantity adjustments
- "Add All to Cart" calls `/recipe/add-to-cart` then refreshes mini-cart

##### [NEW] `public/frontend/assets/css/recipe.css`
- Styles for the recipe modal and cook button

#### Phase 5E: Caching & Rate Limiting

##### [MODIFY] `app/Providers/AppServiceProvider.php`
- Register AI service bindings (`AIManager`, provider interface)
- Configure rate limiter for AI API calls

##### Caching Strategy
- Cache LLM responses keyed by `sha256(recipe_name:servings)` hash
- Use database cache (already configured)
- Configurable TTL via `AI_CACHE_TTL` (default: 1 hour)

##### Rate Limiting
- `/recipe/parse` endpoint: max 5 requests/minute per user/IP
- AI provider calls: max 10 requests/minute (shared across all users)

#### Phase 5F: Error Handling & Security

- Validate recipe input (max 200 chars, sanitize against injection)
- CSRF protection on all endpoints
- Never trust LLM for product IDs, prices, or stock — always verify from DB
- Handle LLM timeouts gracefully (30-second timeout, user-friendly error)
- Log AI interactions for debugging (`storage/logs/ai.log`)
- Graceful degradation when all providers fail

#### Verification — Task 5

##### [NEW] Tests
- `tests/Unit/AI/IngredientNormalizerTest.php` — alias/unit normalization
- `tests/Unit/AI/ProductMatcherTest.php` — matching tiers & confidence
- `tests/Unit/AI/QuantityConversionServiceTest.php` — quantity conversions
- `tests/Feature/AI/RecipeParseTest.php` — end-to-end recipe parsing
- `tests/Feature/AI/RecipeAddToCartTest.php` — adding matched items to cart
- `tests/Feature/AI/AIProviderFallbackTest.php` — Groq → OpenRouter → Cloudflare fallback
- `tests/Feature/AI/AIRateLimitTest.php` — rate limiting behavior

```bash
php artisan test --filter=AI         # Run all AI-related tests
php artisan test                      # Full test suite
```

---

## Verification Plan

### Automated Tests (after each task)

```bash
# After Task 1 (Upgrade)
php artisan --version && php artisan test && php artisan route:list --compact

# After Task 2 (Data Migration)
php artisan test --filter=DataMigration

# After Task 3 (Rebranding)
php artisan test --filter=Rebranding

# After Task 5 (AI Feature)
php artisan test --filter=AI

# Full suite
php artisan test
```

### Manual Verification Checklist

- [ ] **Homepage**: Products display with correct images, categories load, search works
- [ ] **Product Pages**: Product details, images, variants, inventory status correct
- [ ] **Cart Flow**: Add to cart → view cart → update qty → apply coupon → checkout
- [ ] **Admin Panel**: Login → dashboard → manage products, categories, orders
- [ ] **Recipe Feature**: Enter "Channa Masala" → review modal → adjust → add to cart
- [ ] **Logo & Branding**: No "Indian Punjabi Bazaar" or "ipbgrocery" anywhere
- [ ] **Email**: Verify sender shows `noreply@punjabimandi.com`

---

## Execution Order & Dependencies

```mermaid
graph TD
    A["Task 1: Laravel Upgrade<br/>11 → 12 → 13"] --> B["Task 2: Data Migration<br/>from Bagisto"]
    B --> C["Task 3: Rebranding<br/>to Punjabi Mandi"]
    C --> D["Task 4: Frontend UI<br/>(Awaiting Design)"]
    C --> E["Task 5: AI Cook &<br/>Auto-Fill Cart"]
    D -.-> E
```

> [!NOTE]
> Tasks 4 and 5 can be worked on in parallel once Tasks 1-3 are complete. Task 4 is deferred pending your design delivery. Task 5 can begin immediately after Task 3.

---

## Change Report (Excel)

An Excel report file `change_report.xlsx` is maintained in the project root at [`c:\laragon\www\punjabimandi\change_report.xlsx`](file:///c:/laragon/www/punjabimandi/change_report.xlsx).

This file is **automatically updated after each phase** and contains:

| Column | Description |
|--------|-------------|
| **Phase** | Task & Phase ID (e.g., "Task 1 - Phase 1A") |
| **Phase Name** | Human-readable name |
| **File/Component** | File path or component changed |
| **Change Type** | NEW / MODIFY / DELETE / CONFIG |
| **Description** | What was changed and why |
| **Status** | ✅ Complete / 🔄 In Progress / ⏳ Pending |
| **Completed At** | Timestamp of completion |
| **Test Result** | PASS / FAIL / N/A |
| **Notes** | Any issues, warnings, or observations |

The report is generated using `PhpSpreadsheet` via a helper script at `scripts/update_change_report.php`.

---

## Estimated Effort

| Task | Estimated Time | Status |
|------|---------------|--------|
| Task 1: Laravel Upgrade | 3-4 hours | Ready to start |
| Task 2: Data Migration | 4-6 hours | Depends on Task 1 |
| Task 3: Rebranding | 1-2 hours | Depends on Task 1 |
| Task 4: Frontend UI | TBD (awaiting design) | Deferred |
| Task 5: AI Cook Feature | 6-8 hours | Depends on Tasks 1-3 |
| **Total (Tasks 1-3, 5)** | **~14-20 hours** | |
