This is the consolidated documentation set for Cartly.
- Architecture: ARCHITECTURE.md
- Setup & Dev: SETUP.md
- Features: FEATURES.md
- Operations: OPERATIONS.md
- UI & Theme: UI_THEME.md
- Database: DATABASE.md
- Email (transactional): EMAIL.md
- User ownership model: USER_OWNERSHIP.md
- Storefront semantics: STOREFRONT_SEMANTICS.md
- Cursor/editor rules:
.cursor/rules/(project-specific rules for Cursor and AI-assisted editing)
Cartly is a multi-tenant e‑commerce SaaS built with Slim + Twig + Eloquent. It includes:
- Landing (public marketing)
- Admin/Root panel (management)
- Storefront (shop domains)
- Start server: php cartly serve
- Migrate DB: php cartly migrate
- Seed demo: php cartly db:seed --demo
- Session-based auth (primary)
- Admin login at /admin/login
- CSRF protection enforced for state-changing requests
- India-first defaults (INR, IST, GST, DD‑MM‑YYYY)
src/Services: classes with side effects or external dependencies (DB, API, filesystem, sessions).src/Helpers: stateless utilities (pure functions, formatting, URL helpers).src/Factories: object creation/builders (e.g., logger factories).
Use lazy getters in AppController for optional helpers (e.g., $this->pagination(), $this->session()), so controllers opt in only when needed.
Use PaginationService::paginate() in list controllers to keep index methods thin and consistent.
Use structured POST data for forms (e.g., shop[...], user[...], subscription[...], payment[...], package[...]) so controllers can create models with a single array and keep validation keys consistent.
Use the shared component classes for consistent spacing and alignment across all admin forms.
- Wrap each admin page content in a
card bg-base-100 border border-base-300withadmin-card-body. - Use
admin-form-gridfor two-column sections (auto stacks on mobile). - Group related fields inside grey cards
card bg-base-200/40 border border-base-300. - Use
admin-form-actionsfor action button rows.
- Use
admin-form-controlfor every field wrapper (standard gap). - Inputs:
admin-input - Selects:
admin-select - Textareas:
admin-textarea
- Always include matching
forandid. - Use
<span class="label-text font-semibold">Label</span>for labels. - Add
<span class="text-error">*</span>for required fields. - Include CSRF tokens in every form.
- Use
admin-tablefor list tables. - Keep hover on rows (
class="hover"ontr).
- All forms must use PRG to avoid browser back-button POST warnings.
- On validation failure: store
errors+oldin session flash, then redirect back to the form route. - On GET: read flash
errors/oldand pass to the view.
- Use
FlashService::set('success'|'error'|'info'|'warning', message)after create/update/delete actions. - Admin layouts render flash toasts globally, so modules only need to set the flash and redirect.
- Use Valitron in each controller for form validation.
- Keep error keys aligned to form field names (e.g.,
errors.email). - Add DB-dependent checks (uniqueness/existence) after Valitron validation.