# Phase 2.1 Status Report — Safe Checkpoint

**Date:** 2026-08-12  
**Status:** PAUSED AT SAFE CHECKPOINT  
**Repository State:** STABLE AND BUILDABLE  
**Continuation Required:** YES

---

## Executive Summary

Phase 2.1 (Architectural Correction & Hardening) has been **partially completed** and is now at a safe checkpoint. The repository is in a working, buildable state with critical architectural corrections applied. The i18n/RTL implementation has been **deferred** to avoid leaving the repository in a broken state.

**This phase is NOT complete and must be continued in a fresh session.**

---

## ✅ COMPLETED WORK

### 1. Schema.org Product → Service Migration ✅

**File Changed:** `apps/web/lib/seo/schema.ts`

**Changes:**
- Replaced `@type: 'Product'` with `@type: 'Service'`
- Added `serviceType` field (using service name)
- Added `areaServed` field (United Arab Emirates)
- Added `provider` field (Shinecode Organization)
- Updated comments to clarify Shinecode sells services, not physical products
- Updated offer URL to include `/en/` locale prefix (preparatory)

**Rationale:** Shinecode provides at-home beauty/wellness services, not physical products for sale. Schema.org Service type is semantically correct.

**Validation:** Build passes, schema generates correctly.

---

### 2. Route Group Rename: (marketplace) → (services) ✅

**Directory Renamed:** `apps/web/app/(marketplace)` → `apps/web/app/(services)`

**Changes:**
- Internal route group naming changed
- **Public URLs unchanged:** `/services/[slug]`, `/categories/[slug]`, `/search`
- Route group is implementation detail only

**Rationale:** "Marketplace" is generic and commercially limiting. "Services" is clearer and more accurate.

**Validation:** Build passes, routing works correctly.

---

### 3. Verification: No Provider Routes ✅

**Confirmed:**
- No `/providers/` routes exist
- No `/providers/[id]/` routes exist
- No provider schemas exist
- No provider browsing implemented
- No provider availability checking
- Broadcast dispatch model preserved

**Validation:** File search confirms zero provider-related routes or schemas.

---

### 4. Verification: No PostgreSQL References ✅

**Confirmed:**
- All documentation correctly states MySQL 8
- No PostgreSQL references in docs/
- No `pgsql` or `postgres` configuration

**Validation:** `grep -r "postgres\|PostgreSQL" docs/` returns zero results.

---

### 5. Verification: No Vercel References ✅

**Confirmed:**
- All documentation correctly states VPS deployment
- No Vercel deployment configuration
- No Vercel-specific features referenced

**Validation:** `grep -r "Vercel\|vercel" docs/` returns zero results.

---

### 6. Verification: Laravel 13 Documentation ✅

**Confirmed:**
- All documentation correctly states Laravel 13
- PHP 8.3 specified
- MySQL 8 specified

**Validation:** Previous Phase 0 corrections remain intact.

---

### 7. Translation Files Prepared (Safe State) ✅

**Files Created:**
- `apps/web/messages/en.json` (English translations)
- `apps/web/messages/ar.json` (Arabic translations)

**Content:**
- Comprehensive translation keys for common, navigation, services, categories, search, errors, SEO
- Organized by domain (not flat structure)
- Includes RTL-appropriate Arabic translations
- Includes pluralization support

**Status:** Files exist but are **not yet integrated** into components. This is safe—they don't break the build.

---

## ⚠️ INCOMPLETE WORK (Safe Checkpoint)

### 8. next-intl Installation — REVERTED ⚠️

**Action Taken:** Installed, then **uninstalled** to restore clean state

**Rationale:** next-intl requires:
- Middleware configuration
- All page components refactored for `[locale]` param
- All metadata functions refactored
- Root layout changes
- Type configuration

**Status:** Dependency removed. Translation files preserved for future use.

---

### 9. Locale-Based URL Structure — NOT IMPLEMENTED ⚠️

**Required Architecture:**
```
app/
├── [locale]/
│   ├── (services)/
│   │   ├── services/[slug]/
│   │   ├── categories/[slug]/
│   │   └── search/
│   ├── layout.tsx
│   └── page.tsx
```

**Current Architecture:**
```
app/
├── (services)/
│   ├── services/[slug]/
│   ├── categories/[slug]/
│   └── search/
├── layout.tsx
└── page.tsx
```

**Status:** NOT migrated. Requires systematic refactoring of all pages.

---

### 10. RTL Support — NOT IMPLEMENTED ⚠️

**Required:**
- Root layout with `<html dir="ltr|rtl">`
- CSS logical properties throughout:
  - `margin-inline-start` instead of `margin-left`
  - `padding-inline-end` instead of `padding-right`
  - `inset-inline-*` instead of `left`/`right`
  - `text-align: start` instead of `text-align: left`
- Tailwind logical utility classes
- Directional icon mirroring evaluation

**Status:** NOT implemented. All current CSS uses physical properties.

---

### 11. Localized Metadata & Hreflang — NOT IMPLEMENTED ⚠️

**Required:**
- `generateMetadata()` functions accept locale parameter
- Localized titles and descriptions
- Canonical URLs include locale
- hreflang alternates for en/ar
- `x-default` hreflang

**Status:** NOT implemented. Current metadata is English-only.

---

### 12. Localized Sitemap — NOT IMPLEMENTED ⚠️

**Current:** `apps/web/app/sitemap.ts` generates:
- `/services/[slug]`
- `/categories/[slug]`
- `/search`

**Required:**
- `/en/services/[slug]`
- `/ar/services/[slug]`
- `/en/categories/[slug]`
- `/ar/categories/[slug]`
- `/en/search`
- `/ar/search`

**Status:** NOT implemented. Current sitemap is non-localized.

---

### 13. Search Indexability Audit — NOT IMPLEMENTED ⚠️

**Required:**
- Search page at `/[locale]/search` should be indexable
- Arbitrary search query URLs like `/[locale]/search?q=cleaning` should have `noindex, follow` robots meta
- Requires metadata logic in search page

**Status:** NOT audited or implemented.

---

### 14. Laravel Search API Integration — NOT IMPLEMENTED ⚠️

**Current:** `apps/web/app/api/search/route.ts`
- Fetches all services from API
- Filters locally in Next.js
- Duplicates search logic

**Required:**
- Use Laravel's existing `/search-list` endpoint
- Backend provides search logic
- Frontend displays results only

**Status:** NOT implemented. Current implementation uses local filtering.

---

### 15. Revalidation Endpoint Hardening — NOT IMPLEMENTED ⚠️

**Current:** `apps/web/app/api/revalidate/route.ts`
- Basic secret authentication
- Accepts arbitrary tags

**Required:**
- Constant-time secret comparison
- Tag allowlist or strict validation
- Rate limiting (optional)
- Prevent cache tag injection
- Structured logging
- Never expose secret in response

**Status:** NOT hardened. Basic implementation remains.

---

### 16. Documentation Updates — NOT COMPLETED ⚠️

**Files Requiring Updates:**
- `docs/ARCHITECTURE.md` — Add i18n architecture, locale routing
- `docs/FRONTEND.md` — Add next-intl, RTL requirements
- `docs/API_CONTRACTS.md` — Add localized content requirements
- `docs/SEO.md` — Add hreflang, localized sitemap, search strategy
- `docs/SECURITY.md` — Add revalidation hardening
- `docs/PERFORMANCE.md` — Add locale-aware caching
- `docs/ACCESSIBILITY.md` — Add RTL requirements
- `docs/DECISIONS.md` — Add ADRs for Service schema, route renaming, i18n strategy
- `.ai/AGENTS.md` — Add all Phase 2.1 architectural rules

**Status:** NOT updated. Documentation does not yet reflect Phase 2.1 changes.

---

### 17. AGENTS.md Update — NOT COMPLETED ⚠️

**Required Rules for Future AI Agents:**

**NEVER:**
- Create provider profiles, browsing, availability, or selection
- Use Product schema for Shinecode services
- Introduce Vercel, serverless, or managed frontend hosting
- Assume PostgreSQL (MySQL 8 only)
- Assume Laravel 11 (Laravel 13 only)
- Create booking UI in Next.js (Laravel Blade only)
- Duplicate Laravel API logic in frontend
- Hardcode English strings in reusable UI
- Implement RTL with random left/right CSS hacks
- Expose secrets to client code
- Index arbitrary search query pages
- Use "marketplace" terminology for route groups

**ALWAYS:**
- Use Laravel 13 + PHP 8.3 + MySQL 8
- Use VPS deployment
- Preserve service-centric architecture (no providers)
- Hard booking handoff to `booking.shinecode.ae` with `service_id`
- Support English and Arabic with /en/ and /ar/ URLs
- Support LTR and RTL with logical CSS properties
- Use localized SEO (canonical, hreflang, sitemap)
- Use Service structured data (not Product)
- Keep server-first rendering
- Preserve strict TypeScript
- Use Laravel search API (not local filtering)
- Use route group `(services)` (not `(marketplace)`)

**Status:** NOT added to `.ai/AGENTS.md`.

---

## 📁 FILES CHANGED (This Session)

### Modified:
1. `apps/web/lib/seo/schema.ts` — Product → Service schema
2. `apps/web/next.config.ts` — Restored clean config (removed incomplete intl)

### Created:
3. `apps/web/messages/en.json` — English translations (prepared, not integrated)
4. `apps/web/messages/ar.json` — Arabic translations (prepared, not integrated)
5. `docs/PHASE_2_1_STATUS.md` — This document

### Renamed:
6. `apps/web/app/(marketplace)/` → `apps/web/app/(services)/`

### Temporarily Created Then Removed (Safe Checkpoint):
- `apps/web/middleware.ts` — Removed
- `apps/web/i18n.ts` — Removed
- `apps/web/app/[locale]/` — Removed
- `next-intl` dependency — Uninstalled

---

## 🏗️ CURRENT REPOSITORY STATE

### Route Structure:
```
apps/web/app/
├── (services)/
│   ├── services/
│   │   └── [slug]/
│   │       └── page.tsx
│   ├── categories/
│   │   └── [slug]/
│   │       └── page.tsx
│   ├── search/
│   │   └── page.tsx
│   └── layout.tsx
├── api/
│   ├── search/
│   │   └── route.ts
│   └── revalidate/
│       └── route.ts
├── layout.tsx
├── page.tsx
├── sitemap.ts
└── robots.ts
```

### Public URLs (Current):
- `/services/[slug]` — Service detail
- `/categories/[slug]` — Category listing
- `/search` — Search page
- `/sitemap.xml` — Sitemap
- `/robots.txt` — Robots

### Public URLs (Target):
- `/en/services/[slug]` — English service detail
- `/ar/services/[slug]` — Arabic service detail
- `/en/categories/[slug]` — English category listing
- `/ar/categories/[slug]` — Arabic category listing
- `/en/search` — English search
- `/ar/search` — Arabic search
- `/sitemap.xml` — Localized sitemap (both languages)
- `/robots.txt` — Robots

### Schema Implementation (Current):
```typescript
{
  "@type": "Service",  // ✅ Correct
  "serviceType": "...",
  "areaServed": { "@type": "Country", "name": "UAE" },
  "provider": { "@type": "Organization", "name": "Shinecode" },
  "offers": { ... },
  "aggregateRating": { ... }
}
```

---

## 🔧 VALIDATION COMMANDS

### TypeScript Check:
```bash
cd /home/sc/shinecode_frontend
npm run type-check
```
**Expected:** ✅ No errors

### Build Test:
```bash
cd /home/sc/shinecode_frontend/apps/web
npm run build
```
**Expected:** ✅ Successful build

### Lint Check:
```bash
cd /home/sc/shinecode_frontend
npm run lint
```
**Expected:** ✅ Passes (or minor warnings)

### Route Verification:
```bash
cd /home/sc/shinecode_frontend/apps/web
find app -name "provider*" -o -name "*marketplace*"
```
**Expected:** Zero results (except this may show old string matches in comments)

### Schema Verification:
```bash
cd /home/sc/shinecode_frontend/apps/web
grep -n "Product" lib/seo/schema.ts
```
**Expected:** Only in comments explaining why we DON'T use Product schema

---

## 🚨 RISKS & BLOCKERS

### Risk 1: Laravel API Localization
**Issue:** Laravel API may not currently provide:
- Localized service names
- Localized category names
- Localized descriptions
- Localized slugs
- Language-specific content

**Impact:** Frontend cannot generate real localized pages without backend support.

**Mitigation:** 
- Document API contract requirements
- Design frontend architecture to support localized data when available
- Do NOT fake translations in frontend
- Do NOT generate Arabic SEO pages with English content

**Action Required:** Audit Laravel API for locale/language fields before continuing i18n implementation.

---

### Risk 2: Localized Slugs
**Issue:** Service/category slugs may be English-only in database.

**Examples:**
- English: `/en/services/home-cleaning`
- Arabic: `/ar/services/تنظيف-المنزل` ← May not exist in API

**Impact:** Cannot create truly localized URLs without backend support.

**Mitigation:**
- Check if Laravel provides `slug_en` and `slug_ar` fields
- If not, use English slugs for both languages temporarily
- Design abstraction layer to swap in localized slugs later
- Document as API requirement

**Action Required:** Inspect Laravel Service and Category models for localization fields.

---

### Risk 3: ISR Cache Tags with Locales
**Issue:** Current cache tags don't include locale.

**Current:** `['services', 'service-{slug}']`  
**Required:** `['services-en', 'services-ar', 'service-{slug}-en', 'service-{slug}-ar']`

**Impact:** Cache invalidation may affect wrong locale.

**Mitigation:** Update cache tag strategy before implementing locales.

---

### Risk 4: Booking Handoff URL
**Issue:** Current booking URL doesn't include locale context.

**Current:** `https://booking.shinecode.ae/booking/initiate?service_id=123`  
**Consider:** Should it be `?service_id=123&locale=ar`?

**Action Required:** Clarify if Laravel booking flow needs locale parameter.

---

## 📋 REMAINING WORK CHECKLIST

### Phase 2.1 Continuation:

#### A. Install & Configure next-intl
- [ ] `npm install next-intl`
- [ ] Create `i18n.ts` configuration
- [ ] Create `middleware.ts` for locale routing
- [ ] Update `next.config.ts` with `createNextIntlPlugin`
- [ ] Configure TypeScript for next-intl types

#### B. Migrate Route Structure
- [ ] Create `app/[locale]/` directory
- [ ] Move `(services)/` into `[locale]/`
- [ ] Update all page components to accept `params.locale`
- [ ] Update all `generateStaticParams()` to include locales
- [ ] Update all `generateMetadata()` to use locale
- [ ] Test routing for both `/en/...` and `/ar/...`

#### C. Implement Localized Metadata
- [ ] Create `lib/seo/metadata.ts` helper
- [ ] Implement `createLocalizedMetadata()` function
- [ ] Add canonical URL logic (locale-aware)
- [ ] Add hreflang alternates (en, ar, x-default)
- [ ] Update all page `generateMetadata()` to use helper
- [ ] Verify Open Graph metadata includes locale

#### D. Implement RTL Support
- [ ] Update root layout: `<html lang={locale} dir={locale === 'ar' ? 'rtl' : 'ltr'}>`
- [ ] Audit all CSS for physical properties (left, right, padding-left, etc.)
- [ ] Replace with logical properties:
  - `margin-left` → `margin-inline-start`
  - `margin-right` → `margin-inline-end`
  - `padding-left` → `padding-inline-start`
  - `padding-right` → `padding-inline-end`
  - `left` → `inset-inline-start`
  - `right` → `inset-inline-end`
  - `text-align: left` → `text-align: start`
- [ ] Update Tailwind usage with logical utilities where possible
- [ ] Evaluate directional icons (arrows, chevrons)
- [ ] Test Arabic layout thoroughly

#### E. Update Components for i18n
- [ ] Replace hardcoded strings with `useTranslations()`
- [ ] Update Button component
- [ ] Update Input component
- [ ] Update Badge component
- [ ] Update ServiceCard component
- [ ] Update CategoryPill component
- [ ] Update search page
- [ ] Update service detail page
- [ ] Update category page
- [ ] Update error pages (error.tsx, not-found.tsx, global-error.tsx)
- [ ] Update loading.tsx

#### F. Update Sitemap for Locales
- [ ] Modify `app/sitemap.ts`
- [ ] Generate URLs for both /en/ and /ar/
- [ ] Add locale to lastModified logic
- [ ] Verify x-default points to English
- [ ] Test sitemap.xml output

#### G. Update Robots.txt
- [ ] Verify /en/ and /ar/ paths are allowed
- [ ] Ensure API routes remain disallowed
- [ ] Test robots.txt output

#### H. Implement Search Noindex
- [ ] Update search page metadata
- [ ] Add `robots: { index: false, follow: true }` for query URLs
- [ ] Keep base `/[locale]/search` indexable

#### I. Integrate Laravel Search API
- [ ] Update `apps/web/app/api/search/route.ts`
- [ ] Use Laravel `/search-list` endpoint
- [ ] Remove local service filtering logic
- [ ] Update API client with `searchServices(query, locale)` method
- [ ] Test search functionality

#### J. Harden Revalidation Endpoint
- [ ] Update `apps/web/app/api/revalidate/route.ts`
- [ ] Implement constant-time secret comparison
- [ ] Add tag allowlist or strict validation format
- [ ] Prevent arbitrary cache tag injection
- [ ] Add structured logging (without exposing secret)
- [ ] Consider rate limiting
- [ ] Test with valid/invalid secrets and tags

#### K. Update Documentation
- [ ] `docs/ARCHITECTURE.md` — Add i18n architecture
- [ ] `docs/FRONTEND.md` — Add next-intl and RTL
- [ ] `docs/API_CONTRACTS.md` — Add localized content requirements
- [ ] `docs/SEO.md` — Add hreflang, localized sitemap, search strategy
- [ ] `docs/SECURITY.md` — Add revalidation hardening
- [ ] `docs/PERFORMANCE.md` — Add locale-aware caching
- [ ] `docs/ACCESSIBILITY.md` — Add RTL requirements
- [ ] `docs/DECISIONS.md` — Add ADRs for:
  - ADR-007: Service Schema (not Product)
  - ADR-008: Route Group Rename (services not marketplace)
  - ADR-009: i18n Strategy (next-intl, /en/ /ar/)
  - ADR-010: RTL with Logical CSS Properties
  - ADR-011: Laravel Search API Integration
  - ADR-012: Localized Slugs (API Contract)

#### L. Update AGENTS.md
- [ ] Add all "NEVER" rules from this report
- [ ] Add all "ALWAYS" rules from this report
- [ ] Update skills references
- [ ] Add Phase 2.1 requirements as permanent guidance

#### M. Validation & Testing
- [ ] Run `npm run type-check` across all packages
- [ ] Run `npm run lint` across all packages
- [ ] Run `npm run build` in apps/web
- [ ] Test English routes: `/en/services/...`, `/en/categories/...`, `/en/search`
- [ ] Test Arabic routes: `/ar/services/...`, `/ar/categories/...`, `/ar/search`
- [ ] Test RTL layout visually
- [ ] Test booking handoff with both locales
- [ ] Verify Schema.org Service type
- [ ] Verify hreflang in page source
- [ ] Verify sitemap includes both locales
- [ ] Verify search noindex on query URLs
- [ ] Verify Laravel search API integration
- [ ] Verify revalidation endpoint security

---

## 🎯 API/BACKEND REQUIREMENTS

**These must be clarified with Laravel team before full i18n implementation:**

### 1. Localized Content Fields

Does Laravel provide:
```php
// Service model
$service->name_en
$service->name_ar
$service->description_en
$service->description_ar
$service->slug_en  // e.g., "home-cleaning"
$service->slug_ar  // e.g., "تنظيف-المنزل"
```

Or:
```php
// Service translations table
$service->translate('en')->name
$service->translate('ar')->name
```

**If NO:** Frontend must use English content for both locales temporarily and document requirement.

---

### 2. API Locale Header

Does Laravel API support:
```
Accept-Language: ar
Accept-Language: en
```

Or specific locale parameter:
```
GET /api/service-list?locale=ar
GET /api/service-list?locale=en
```

**If NO:** Frontend receives English-only content.

---

### 3. Search API Localization

Does `/search-list` endpoint support:
```
GET /api/search-list?q=cleaning&locale=en
GET /api/search-list?q=تنظيف&locale=ar
```

**If NO:** Search may only work effectively in English.

---

### 4. Booking Locale Context

Should booking handoff include:
```
https://booking.shinecode.ae/booking/initiate?service_id=123&locale=ar
```

Or does Laravel Blade detect locale from session/domain?

---

## 🔄 RESTORE COMMANDS (If Needed)

If something breaks during continuation:

### Restore to Last Known Good State:
```bash
cd /home/sc/shinecode_frontend
git status
git diff
# Review changes, then:
git restore <file>  # For specific files
# OR
git stash  # To save work-in-progress
```

### Rebuild from Scratch:
```bash
cd /home/sc/shinecode_frontend
rm -rf node_modules apps/web/node_modules packages/*/node_modules
rm -rf apps/web/.next
npm install
cd apps/web && npm run build
```

---

## ✅ ACCEPTANCE CRITERIA (Phase 2.1 Complete)

Phase 2.1 will be **complete** only when:

### Backend Documentation:
- [x] Laravel 13 documented
- [x] PHP 8.3 documented
- [x] MySQL 8 documented
- [x] VPS deployment documented
- [x] No Vercel references
- [x] No PostgreSQL references

### Architecture:
- [x] Product schema removed
- [x] Service schema implemented
- [x] Provider routes absent
- [x] Provider schemas absent
- [ ] Route group is `(services)` ← **DONE but needs docs update**
- [ ] Locale routing `/[locale]/...` implemented

### Internationalization:
- [ ] next-intl installed and configured
- [ ] English locale exists and works
- [ ] Arabic locale exists and works
- [ ] RTL implemented with logical CSS
- [ ] Localized metadata (titles, descriptions)
- [ ] hreflang implemented
- [ ] Localized canonical URLs
- [ ] Localized sitemap

### SEO:
- [ ] Arbitrary search queries are noindex
- [ ] Base search page is indexable
- [ ] Service schema (not Product) in production
- [ ] hreflang validated

### Search:
- [ ] Laravel search API integrated
- [ ] Local filtering removed
- [ ] Search remains functional for users

### Security:
- [ ] Revalidation endpoint hardened
- [ ] Secret comparison is constant-time
- [ ] Tag injection prevented

### Booking:
- [x] Hard redirect to booking.shinecode.ae
- [x] service_id passed
- [ ] Locale context considered (if needed)

### Documentation:
- [ ] All docs updated per checklist
- [ ] AGENTS.md updated with rules
- [ ] DECISIONS.md includes new ADRs

### Validation:
- [ ] TypeScript passes
- [ ] ESLint passes
- [ ] Production build passes
- [ ] English routes work
- [ ] Arabic routes work
- [ ] RTL layout tested
- [ ] Booking handoff tested

---

## 📝 NEXT SESSION COMMANDS

To continue Phase 2.1:

```bash
# 1. Navigate to repository
cd /home/sc/shinecode_frontend

# 2. Verify current state
npm run type-check
cd apps/web && npm run build

# 3. Review status
cat docs/PHASE_2_1_STATUS.md

# 4. Begin implementation (follow checklist above)
# Start with: npm install next-intl
```

---

## ⚠️ FINAL STATUS

**Phase 2.1 is PAUSED at a safe checkpoint and requires continuation.**

**Completed:** 7 of 17 major tasks  
**Repository State:** STABLE, BUILDABLE, TYPE-SAFE  
**Architectural Corrections:** Product→Service schema, route rename, verification complete  
**i18n Implementation:** Translation files prepared, full integration pending  

**DO NOT proceed to Phase 3 until Phase 2.1 is complete and validated.**

---

**End of Phase 2.1 Status Report**
