CLAUDE.md — KodePress project rules#
These rules are binding for every change in this repository. Read this file first, at the start of every session and at the start of every phase. If a rule here conflicts with an instruction in a prompt, say so before writing code.
1. What we are building#
KodePress — a website CMS a non-technical owner can operate alone. Pages, blog posts, menus, mega menus, header, footer and theme are all built from the admin panel, with no code.
Success is measured by one number: a new user, with no training, publishes a first page in under 10 minutes. Every design decision loses to that goal.
The owner is not technical. Keep explanations simple. Add short plain-language comments in code where a non-developer might one day read it (block schemas, settings screens, Artisan commands).
2. Hard constraints#
- Laravel 11, PHP 8.3, MySQL 8, Blade + Livewire 3 + Alpine.js. No React, no Next.js, no Node process at runtime.
- Must run on shared cPanel hosting with SSH only: no Redis, no queue workers, no Docker, no
root, no supervisor. Use the file cache driver, database sessions,
QUEUE_CONNECTION=sync, and the single cPanel cron entry runningphp artisan schedule:runevery minute. - Vite builds locally and built assets are committed, so the server never needs Node.
- Laravel conventions only: Eloquent models, Form Requests, Policies, API Resources, migrations, seeders, Artisan commands, events/listeners. No raw PHP pages, no business logic in Blade.
- No placeholder code. No
TODO, no "implement later", no stubbed method that silently returns null. A feature is either implemented completely or not started. Where a phase explicitly ships a stub (e.g. the Form block in Phase 1), the stub renders a clear, translated "not configured yet" state — it never throws. - Every user-facing string lives in
lang/bnandlang/en. No hard-coded UI text, including validation messages, button labels, empty states and email subjects. - Bengali must render correctly everywhere (Noto Sans Bengali, self-hosted,
font-display: swap). - When two solutions work, take the simpler one that survives shared hosting.
3. Core concept — everything is a block#
A page is a tree: Page → Sections → Columns → Blocks. The whole tree is stored as one JSON
document in page_versions.content. Headers, footers, mega-menu panels and reusable global blocks
use the same tree and the same editor, so the user learns one tool only.
{
"version": 1,
"sections": [
{
"id": "s1",
"settings": { "background": "light", "padding": "large" },
"columns": [
{
"width": 12,
"blocks": [
{ "id": "b1", "type": "heading", "data": { "text": "Hello", "level": 1 } }
]
}
]
}
]
}
The canonical, versioned definition of this format is docs/04-block-system.md. Never change the shape without an ADR and a content migration.
4. Block system#
Each block is a folder: app/Blocks/<Name>/ containing schema.php (fields), view.blade.php
(output) and preview.png. BlockRegistry scans app/Blocks, caches the result, and feeds the
editor. The admin edit form is generated from schema.php.
Field types: text, textarea, richtext (TipTap), image, gallery, link, color, select,
toggle, number, repeater.
Adding a new block must never require editing admin code. If a change to the editor is needed to support a new block, the field type is missing — add the field type, not a special case.
5. Admin panel — exactly 7 sidebar items#
Dashboard, Pages, Blog, Media, Menus, Design (theme, header, footer, saved sections),
Settings (site info, SEO, forms, users, backup, redirects).
Adding an eighth sidebar item requires an ADR. New features go inside one of the seven.
6. Editor rules#
- Live preview in the centre (iframe), outline tree on the left, settings panel on the right.
- The right panel shows only the Content tab by default.
StyleandAdvancedstay collapsed. Add Sectionopens a gallery of ready-made designs, never a blank section.- Drag and drop (SortableJS) for sections and blocks; duplicate, delete, save as template.
- Undo/redo, autosave draft every few seconds, one-click Publish, mobile/tablet/desktop preview.
- Colours, fonts and spacing come from theme tokens only — a user cannot break the design.
- A new site starts with a template picker, never an empty page.
7. Rendering and cache#
On Publish, the JSON tree is rendered to HTML through Blade components and written to the file cache. Visitors are served the cached file.
- A page change clears that page only.
- A change to a menu, header, footer, theme token or global block clears all pages.
Images are auto-compressed, converted to WebP, and given thumbnail/medium/large variants; output is lazy-loaded and the editor prompts for alt text.
8. Roles and security#
- Admin — everything. Editor — pages and blog, may publish. Writer — drafts only. Designer — theme, header, footer, mega-menu layout.
- Optional approval before publish (Writer → Editor).
- Audit log for every create/update/delete/publish.
- Rich text is sanitised server-side (XSS). The HTML block and any custom code are Admin only.
- Uploads are validated by extension and MIME;
php,phtml,exe,sh,svgwith scripts are blocked. CSRF everywhere. Login rate limiting. Optional 2FA (TOTP) for Admin. Changeable admin URL. - Any email/SMS one-time code in this project is 4 digits (authenticator-app TOTP follows RFC 6238 and stays 6).
9. UI rules (house style)#
- Never use browser
alert(),confirm()orprompt(). Use in-app modals and toasts. - Deleting a parent asks about its children explicitly and says what will happen to them.
- Every destructive action is reversible (trash + restore) or confirmed in a modal that names the thing being deleted.
- Dates and times render through one shared helper, never
date()inline.
10. Working method#
- Keep this file current. It is the contract.
- Work phase by phase (docs/16-roadmap-phases.md). At the start of a phase write a short plan, then implement.
- Write Pest feature tests for every phase. Run
php artisan test. Fix failures before moving on. - Seed demo data so the site is visibly working right after
php artisan kodepress:install. - End a phase with a summary under 15 lines, in simple English: what was built, exactly how to try it in the browser (URLs and clicks), and how to deploy that phase to cPanel.
- Ask at most one question at a time, and only when no reasonable default exists.
11. Deployment#
Production is always a git checkout. Deploy = git pull in the live directory, then
composer install --no-dev -o, php artisan migrate --force, cache clears. Never rsync, never edit
files on the server, never deploy from an unpushed commit. After deploying, verify the live HEAD
equals origin/<branch>. Details: docs/14-installation-and-deployment.md.
12. Fixing bugs#
- Reproduce first, then fix, then re-break the fix to prove the test catches it.
- One bug report is a bug class: grep for every sibling occurrence and fix them in the same commit (e.g. if one date render skipped the helper, fix all of them).
- Both sides of a duplicated rule change together — renderer and editor, server validation and client validation.
KodePress documentation · generated from the Markdown sources by
tools/build-docs-site.py · internal preview, not indexed.