Add defaultLocale, EN names, and dashboard activity endpoints.

Expose branding.defaultLocale, optional user EN name fields, and lightweight dual daily activity for orders/customers; update project context and rules.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-01 09:35:27 +03:30
co-authored by Cursor
parent 4598add88c
commit 43e3912662
22 changed files with 331 additions and 15 deletions
+14 -6
View File
@@ -1,7 +1,7 @@
# Meshkee CMS API — Project Context
> Living reference for developers and AI assistants working on this codebase.
> Last updated: July 24, 2026
> Last updated: August 1, 2026
## What This Project Is
@@ -157,6 +157,7 @@ Example super admin: `+989121111111` / `password`
| `038_invoice_templates.sql` | Full invoice templates + key points/accounts on invoices |
| `039_invoice_account_holder.sql` | `account_holder_name` on invoice / template accounts |
| `040_invoice_public_id.sql` | Opaque `public_id` for unguessable public invoice links |
| `049_user_name_en.sql` | Optional `users.first_name_en` / `last_name_en` for EN display names |
Docker mounts `./database/migrations` into Postgres init — migrations run automatically only on **first** volume creation. Use `migrate.sh` for subsequent migrations.
@@ -209,14 +210,20 @@ Invoice.issuedBy → User
Media 1──* MediaAttachment (polymorphic: entityType + entityId)
```
### Schema gap: blogs & portfolios
### Branding & dashboard locale
SQL migrations create `blogs` and `portfolios` tables and seed data populates them. Permissions exist (`blogs.*`, `portfolios.*`). However:
`businesses.settings.branding.defaultLocale` is `'fa' | 'en'` (default **`fa`**). Exposed on tenant resolve and editable from super-admin. Dashboards apply it once on load.
- No Prisma models for Blog/Portfolio
- No NestJS modules or API endpoints
Optional EN name fields: `users.first_name_en` / `last_name_en` (migration `049`).
Categories and media attachments already support `blog` and `portfolio` entity types — infrastructure is ready, API is not.
### Dashboard activity (CMS only — not website-facing)
| Method | Path | Description |
|--------|------|-------------|
| GET | `/businesses/:businessId/orders/activity?days=30` | Dual daily series: orders + cart-item creates |
| GET | `/businesses/:businessId/customers/activity?days=30` | Dual daily series: registrations + active logins (`last_login_at`) |
Lightweight `GROUP BY` counts for business home charts. Requires `orders.read`.
---
@@ -301,6 +308,7 @@ Pattern: `/businesses/:businessId/<resource>`
| Method | Path | Access | Description |
|--------|------|--------|-------------|
| GET | `/orders` | Customer (own) or `orders.read` (all) | List orders |
| GET | `/orders/activity` | Admin `orders.read` | Daily order + cart-add counts |
| GET | `/orders/:orderId` | Customer (own) or `orders.read` | Order detail |
| POST | `/orders` | `orders.create` | Admin: create order for a customer |
| PATCH | `/orders/:orderId` | `orders.update` | Admin: update status / admin notes |
+1
View File
@@ -83,6 +83,7 @@
"slug": { "type": "string" },
"domain": { "type": "string" },
"primaryColor": { "type": "string", "nullable": true },
"defaultLocale": { "type": "string", "enum": ["en", "fa"] },
"logoUrl": { "type": "string", "nullable": true },
"faviconUrl": { "type": "string", "nullable": true }
}