CLAUDE.md
CLAUDE.md/CLAUDE.mdCLAUDE.md
Quality
77/100
Scores the file, not the repository.Length
2,402 words
41 headings · 7 code blocksRepository
0
— · pushed 120 days agoLast changed
3 days ago
First indexed 3 days ago.1# CLAUDE.md — Glomon Homes Real Estate Website23## Project Overview45**Company:** Glomon Homes6**Tagline:** *Find Your Place in Uganda*7**Type:** Full-stack real estate listings and property development website8**Market:** Uganda — primary focus on Kampala and surrounding areas (Wakiso, Mukono, Entebbe corridor)9**Target Audience:**10- Local Ugandan buyers and renters11- Ugandan diaspora investing from abroad12- Expats relocating to Uganda13- Property investors seeking development opportunities1415---1617## Tech Stack1819### Frontend20- **Framework:** React 18 + Vite21- **Styling:** Tailwind CSS v322- **Routing:** React Router v623- **State Management:** React Context API (no Redux — keep it lean)24- **HTTP Client:** Axios25- **Icons:** Lucide React26- **Image Handling:** Cloudinary (free tier) for property images27- **Environment Variables:** `.env` using `VITE_` prefix2829### Backend30- **Runtime:** Node.js (v18+)31- **Framework:** Express.js32- **ORM:** Prisma33- **Database:** PostgreSQL (hosted on Supabase)34- **Auth:** JSON Web Tokens (JWT) for admin authentication35- **File Uploads:** Multer + Cloudinary SDK36- **Validation:** Zod37- **Environment Variables:** dotenv3839### Database40- **Provider:** Supabase (PostgreSQL)41- **ORM:** Prisma with migrations4243### Deployment44- **Frontend:** Vercel45- **Backend:** Railway46- **Database:** Supabase (free tier)47- **Images:** Cloudinary (free tier)4849---5051## Folder Structure5253```54glomon-homes/55├── CLAUDE.md56├── .gitignore57├── README.md58│59├── frontend/60│ ├── public/61│ │ └── favicon.ico62│ ├── src/63│ │ ├── assets/64│ │ │ └── logo.svg65│ │ ├── components/66│ │ │ ├── layout/67│ │ │ │ ├── Navbar.jsx68│ │ │ │ └── Footer.jsx69│ │ │ ├── properties/70│ │ │ │ ├── PropertyCard.jsx71│ │ │ │ ├── PropertyGrid.jsx72│ │ │ │ ├── PropertyFilters.jsx73│ │ │ │ └── PropertyImageGallery.jsx74│ │ │ ├── ui/75│ │ │ │ ├── Button.jsx76│ │ │ │ ├── Badge.jsx77│ │ │ │ ├── Spinner.jsx78│ │ │ │ └── Modal.jsx79│ │ │ └── forms/80│ │ │ ├── EnquiryForm.jsx81│ │ │ └── ContactForm.jsx82│ │ ├── pages/83│ │ │ ├── HomePage.jsx84│ │ │ ├── ListingsPage.jsx85│ │ │ ├── PropertyDetailPage.jsx86│ │ │ ├── AboutPage.jsx87│ │ │ ├── ContactPage.jsx88│ │ │ └── NotFoundPage.jsx89│ │ ├── admin/90│ │ │ ├── AdminLoginPage.jsx91│ │ │ ├── AdminDashboard.jsx92│ │ │ ├── AdminProperties.jsx93│ │ │ ├── AdminAddProperty.jsx94│ │ │ ├── AdminEditProperty.jsx95│ │ │ └── AdminEnquiries.jsx96│ │ ├── context/97│ │ │ └── AuthContext.jsx98│ │ ├── hooks/99│ │ │ ├── useProperties.js100│ │ │ └── useEnquiries.js101│ │ ├── services/102│ │ │ └── api.js103│ │ ├── utils/104│ │ │ └── formatters.js105│ │ ├── App.jsx106│ │ └── main.jsx107│ ├── index.html108│ ├── vite.config.js109│ ├── tailwind.config.js110│ └── package.json111│112└── backend/113 ├── prisma/114 │ ├── schema.prisma115 │ └── seed.js116 ├── src/117 │ ├── routes/118 │ │ ├── properties.js119 │ │ ├── enquiries.js120 │ │ └── auth.js121 │ ├── controllers/122 │ │ ├── propertiesController.js123 │ │ ├── enquiriesController.js124 │ │ └── authController.js125 │ ├── middleware/126 │ │ ├── authMiddleware.js127 │ │ ├── validateRequest.js128 │ │ └── errorHandler.js129 │ ├── lib/130 │ │ └── prisma.js131 │ └── index.js132 ├── .env133 └── package.json134```135136---137138## Database Schema (Prisma)139140```prisma141// prisma/schema.prisma142143generator client {144 provider = "prisma-client-js"145}146147datasource db {148 provider = "postgresql"149 url = env("DATABASE_URL")150}151152model Property {153 id String @id @default(cuid())154 title String155 description String156 price Float157 priceType PriceType @default(SALE)158 currency String @default("UGX")159 propertyType PropertyType160 status ListingStatus @default(ACTIVE)161 bedrooms Int?162 bathrooms Int?163 area Float? // square meters164 location String // e.g. "Kololo, Kampala"165 district String // e.g. "Kampala"166 address String?167 latitude Float?168 longitude Float?169 images String[] // Cloudinary URLs170 coverImage String? // Main display image URL171 featured Boolean @default(false)172 amenities String[] // e.g. ["Parking", "Security", "Swimming Pool"]173 enquiries Enquiry[]174 createdAt DateTime @default(now())175 updatedAt DateTime @updatedAt176}177178model Enquiry {179 id String @id @default(cuid())180 name String181 email String182 phone String?183 message String184 propertyId String?185 property Property? @relation(fields: [propertyId], references: [id])186 status EnquiryStatus @default(NEW)187 createdAt DateTime @default(now())188}189190model AdminUser {191 id String @id @default(cuid())192 email String @unique193 password String // bcrypt hashed194 createdAt DateTime @default(now())195}196197enum PropertyType {198 APARTMENT199 HOUSE200 VILLA201 COMMERCIAL202 LAND203 OFFICE204}205206enum PriceType {207 SALE208 RENT209}210211enum ListingStatus {212 ACTIVE213 INACTIVE214 SOLD215 RENTED216}217218enum EnquiryStatus {219 NEW220 READ221 REPLIED222}223```224225---226227## API Endpoints228229### Public Endpoints230231| Method | Route | Description |232|--------|-------|-------------|233| GET | `/api/properties` | Get all active properties (with filters) |234| GET | `/api/properties/featured` | Get featured properties (for homepage) |235| GET | `/api/properties/:id` | Get single property detail |236| POST | `/api/enquiries` | Submit a property enquiry |237| POST | `/api/enquiries/general` | Submit a general contact message |238| POST | `/api/auth/login` | Admin login — returns JWT |239240### Admin Endpoints (JWT required)241242| Method | Route | Description |243|--------|-------|-------------|244| GET | `/api/admin/properties` | Get all properties including inactive |245| POST | `/api/admin/properties` | Create a new property |246| PUT | `/api/admin/properties/:id` | Update a property |247| DELETE | `/api/admin/properties/:id` | Delete a property |248| PATCH | `/api/admin/properties/:id/status` | Toggle active/inactive/sold |249| GET | `/api/admin/enquiries` | Get all enquiries |250| PATCH | `/api/admin/enquiries/:id/status` | Update enquiry status |251252### Query Parameters for GET /api/properties253254```255?type=APARTMENT|HOUSE|VILLA|LAND|COMMERCIAL256?priceType=SALE|RENT257?district=Kampala|Wakiso|Mukono|Entebbe258?minPrice=50000000259?maxPrice=500000000260?bedrooms=2261?featured=true262?page=1263?limit=12264```265266---267268## Pages & Features269270### 1. Home Page (`/`)271272**Sections:**273- **Hero** — Full-width banner with tagline *"Find Your Place in Uganda"*, a prominent search bar (location + type + price range), and a CTA button "Browse Properties"274- **Featured Listings** — Grid of 6 featured property cards pulled from the API275- **Why Glomon Homes** — 3-column trust section: "Verified Listings", "Local Expertise", "Transparent Pricing"276- **Property Types** — Icon grid: Apartments, Houses, Land, Commercial — each links to filtered listings277- **Locations We Cover** — Kampala, Wakiso, Entebbe, Mukono, Jinja — with property counts278- **Testimonials** — 3 static testimonial cards (hardcoded, not from DB)279- **CTA Banner** — "List Your Property With Us" — links to contact page280- **Footer** — Logo, links, socials, contact info281282---283284### 2. Listings Page (`/listings`)285286**Features:**287- Sidebar filters: Property Type, Price Type (Sale/Rent), District, Bedrooms, Price Range288- Results grid — 12 per page with pagination289- Sort options: Newest, Price Low-High, Price High-Low290- Results count displayed ("34 properties found")291- Each card shows: cover image, title, price, location, bed/bath/area icons, a "View Details" button292- Empty state with friendly message if no results match filters293- Loading skeleton cards while fetching294295---296297### 3. Property Detail Page (`/listings/:id`)298299**Sections:**300- **Image Gallery** — Main image + thumbnail strip, click to expand (lightbox)301- **Property Header** — Title, price, badge (For Sale / For Rent), status badge302- **Key Stats Row** — Bedrooms | Bathrooms | Area (sqm) | Property Type303- **Description** — Full property description text304- **Amenities** — Icon list of all amenities305- **Location** — District + address text (no map required for MVP, add later)306- **Enquiry Form** — Sidebar form: Name, Email, Phone, Message — POST to `/api/enquiries`307- **Related Properties** — 3 similar properties in the same district308309---310311### 4. About Page (`/about`)312313**Content (static):**314- Company story — Glomon Homes is a Ugandan property development and real estate listings company founded with a mission to make quality housing accessible and transparent for Ugandans at home and abroad.315- Mission & Vision statements316- Team section (placeholder cards — 3 members)317- Stats row: "200+ Listings", "5 Districts", "Trusted by Buyers Across Uganda"318319---320321### 5. Contact Page (`/contact`)322323**Features:**324- General contact form: Name, Email, Phone, Subject, Message325- POST to `/api/enquiries/general`326- Company contact info: email, phone, physical address (Kampala)327- Success message on submission328329---330331### 6. Admin Portal (`/admin`)332333**Protected by JWT — redirect to `/admin/login` if not authenticated.**334335**Admin Login (`/admin/login`):**336- Email + Password form337- On success → store JWT in localStorage → redirect to dashboard338339**Admin Dashboard (`/admin/dashboard`):**340- Summary cards: Total Properties, Active Listings, Total Enquiries, New (Unread) Enquiries341- Quick links to manage properties and view enquiries342343**Admin — Properties (`/admin/properties`):**344- Table of all properties with columns: Image, Title, Type, Price, District, Status, Actions345- Actions: Edit, Toggle Status (Active/Inactive/Sold), Delete346- "Add New Property" button → goes to add form347348**Admin — Add/Edit Property (`/admin/properties/new` and `/admin/properties/:id/edit`):**349- Form fields: Title, Description, Property Type, Price, Price Type, Currency, Bedrooms, Bathrooms, Area, Location, District, Address, Amenities (checkboxes), Featured toggle, Status350- Image upload (multiple) via Cloudinary351- Cover image selector from uploaded images352- Save / Cancel buttons353354**Admin — Enquiries (`/admin/enquiries`):**355- Table: Name, Email, Phone, Property (linked), Message preview, Date, Status356- Click row to expand full message357- Mark as Read / Replied actions358359---360361## Design Direction362363### Brand Identity364- **Name:** Glomon Homes365- **Tagline:** *Find Your Place in Uganda*366- **Tone:** Professional, warm, trustworthy — not corporate and cold367- **Feel:** Modern African real estate — clean but with warmth and local character368369### Color Palette370```css371--color-primary: #1B4332; /* Deep forest green — main brand color */372--color-primary-light: #2D6A4F; /* Lighter green for hover states */373--color-accent: #D4A017; /* Gold/amber — for CTAs, highlights */374--color-accent-hover: #B8860B; /* Darker gold for hover */375--color-bg: #F9F6F0; /* Warm off-white background */376--color-surface: #FFFFFF; /* Card surfaces */377--color-text: #1A1A1A; /* Primary text */378--color-text-muted: #6B7280; /* Secondary/muted text */379--color-border: #E5E0D8; /* Subtle borders */380```381382### Typography383- **Display / Headings:** `Playfair Display` (Google Fonts) — elegant, authoritative384- **Body:** `DM Sans` (Google Fonts) — clean, readable, modern385386### UI Principles387- Generous white space — never crowded388- Rounded corners: `border-radius: 12px` on cards, `8px` on buttons and inputs389- Subtle shadows on cards: `box-shadow: 0 2px 16px rgba(0,0,0,0.06)`390- Green primary buttons with gold accent buttons for secondary CTAs391- Property cards show a hover lift effect (`transform: translateY(-4px)`)392- Use badges (pill style) for "For Sale", "For Rent", "Featured"393394---395396## Seed Data397398When running `npx prisma db seed`, populate the database with these sample properties:3994001. **3-Bedroom Apartment in Kololo** — For Sale — UGX 450,000,000 — Kampala — 3 bed / 2 bath / 145 sqm — Amenities: Security, Parking, Generator, Water Tank4012. **2-Bedroom Flat in Ntinda** — For Rent — UGX 1,800,000/month — Kampala — 2 bed / 1 bath / 90 sqm — Amenities: Security, Parking4023. **Executive 4-Bedroom House in Muyenga** — For Sale — UGX 850,000,000 — Kampala — 4 bed / 3 bath / 280 sqm — Amenities: Swimming Pool, Security, Parking, Garden, Generator — Featured: true4034. **Commercial Plot in Namanve** — For Sale — UGX 320,000,000 — Mukono — Land — 0.5 acres4045. **Modern 2-Bedroom Apartment in Entebbe** — For Sale — UGX 290,000,000 — Wakiso — 2 bed / 2 bath / 110 sqm — Amenities: Security, Parking, Lake View — Featured: true4056. **Studio Apartment in Bukoto** — For Rent — UGX 900,000/month — Kampala — 1 bed / 1 bath / 45 sqm — Amenities: Security, WiFi Ready406407Use placeholder images from `https://placehold.co/800x600/1B4332/white?text=Glomon+Homes` for all seed properties.408409---410411## Environment Variables412413### Frontend (`frontend/.env`)414```415VITE_API_URL=http://localhost:5000416VITE_CLOUDINARY_CLOUD_NAME=your_cloudinary_cloud_name417```418419### Backend (`backend/.env`)420```421DATABASE_URL=postgresql://postgres:[PASSWORD]@db.[PROJECT].supabase.co:5432/postgres422JWT_SECRET=your_super_secret_jwt_key_change_this_in_production423PORT=5000424CLOUDINARY_CLOUD_NAME=your_cloudinary_cloud_name425CLOUDINARY_API_KEY=your_cloudinary_api_key426CLOUDINARY_API_SECRET=your_cloudinary_api_secret427ADMIN_EMAIL=admin@glomonhomes.com428ADMIN_PASSWORD=GlomonAdmin2025!429```430431> The `ADMIN_EMAIL` and `ADMIN_PASSWORD` are used by the seed script to create the first admin user.432433---434435## .gitignore436437```438node_modules/439.env440.env.local441dist/442.DS_Store443*.log444```445446---447448## Key Rules for Claude Code4494501. **Never hardcode credentials** — always use environment variables4512. **Always validate inputs** on both frontend (basic) and backend (Zod schemas)4523. **Handle loading and error states** on every API call in the frontend4534. **All admin routes must check JWT** via the `authMiddleware` before processing4545. **Use Prisma client singleton** from `src/lib/prisma.js` — never instantiate it twice4556. **Price formatting:** Always display prices in UGX with comma separators (e.g. UGX 450,000,000). Use a `formatPrice()` utility in `utils/formatters.js`4567. **Images:** If no cover image is available, show the placeholder from placehold.co4578. **Pagination:** Default page size is 12. Always return `{ data, total, page, totalPages }` from paginated endpoints4589. **CORS:** Configure Express to allow requests from `http://localhost:5173` in development and the Vercel domain in production45910. **Error responses:** Always return `{ error: "message" }` format from the API — never expose stack traces in production460461---462463## SEO Implementation (applied 2026-04-01)464465### Package466- `react-helmet-async` installed in `frontend/` — wraps `<App />` with `<HelmetProvider>` in `main.jsx`467468### SEO Component469- `frontend/src/components/SEO.jsx` — reusable component using `react-helmet-async`470- Sets `<title>`, meta description, canonical URL, Open Graph tags, and Twitter Card tags471- Auto-computes canonical from `useLocation()` against `https://glomonhomes.com`472- Appends `| Glomon Homes` to titles that don't already contain the brand name473- Accepts: `title`, `description`, `image`, `type`, `noindex` props474475### Per-page SEO476| Page | Title | Notes |477|------|-------|-------|478| HomePage | Glomon Homes \| Buy, Rent & Invest in Uganda Real Estate | + Organization JSON-LD schema (RealEstateAgent) |479| ListingsPage | Property Listings in Uganda \| Houses, Apartments & Land | H1 updated to "Properties for Sale & Rent in Uganda" |480| PropertyDetailPage | `{title} in {location}` (dynamic) | + RealEstateListing JSON-LD schema; rendered after property loads |481| AboutPage | About Glomon Homes \| Uganda's Trusted Real Estate Company | — |482| ContactPage | Contact Glomon Homes \| Real Estate Enquiries in Uganda | — |483484### Structured Data (JSON-LD)485- **HomePage:** `RealEstateAgent` schema with address, phone, sameAs social links486- **PropertyDetailPage:** `RealEstateListing` schema with offer price, address, image487488### index.html changes489- Updated `<title>` and meta description490- Added `<meta name="robots" content="index, follow">`491- Added `<meta property="og:site_name" content="Glomon Homes">`492- `preconnect` links for Google Fonts already present (kept)493494### Semantic HTML495- `PropertyCard.jsx`: descriptive `aria-label` on `<Link>`, descriptive `alt` text on `<img>`496- `HomePage` hero `<section>`: `aria-label="Hero — Find property in Uganda"`497- Featured section heading updated to "Featured Properties in Uganda"498- Locations section heading updated to "Properties Across Uganda"499500### robots.txt501- `frontend/public/robots.txt` — allows all, disallows `/admin`, references sitemap502503### Sitemap504- `GET /sitemap.xml` endpoint in `backend/src/index.js`505- Queries all `ACTIVE` properties from the database506- Returns valid XML sitemap with static pages + per-property URLs507- Property `lastmod` derived from `updatedAt`508509### Vite build optimisation510- `frontend/vite.config.js` updated with `manualChunks` splitting `vendor` (react, react-dom, react-router-dom) and `ui` (lucide-react, axios)
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| bagisto/bagistoCLAUDE.md · 28k | CLAUDE.md | setupbuildteststyle+5 | 100/100 | 3 days ago | |
| livewire/livewireCLAUDE.md · 24k | CLAUDE.md | setupbuildteststyle+4 | 100/100 | 3 days ago | |
| dotCMS/corecore-web/CLAUDE.md · 949 | CLAUDE.md | teststylearchtesting-strategy+3 | 100/100 | 3 days ago | |
| nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.4k | CLAUDE.md | setupbuildstylearch+2 | 100/100 | 3 days ago | |
| microsoft/playwrightCLAUDE.md · 94k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 3 days ago | |
| filamentphp/filamentCLAUDE.md · 32k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 3 days ago | |
| Adit-Jain-srm/NightmareNetCLAUDE.md · 45 | CLAUDE.md | buildtestlint-formatstyle+6 | 100/100 | 3 days ago | |
| dotCMS/coreCLAUDE.md · 949 | CLAUDE.md | setupbuildteststyle+7 | 99/100 | today |
