Expand invoices with full templates, public viewer API, and account holder.

Add invoice template CRUD, key points/accounts, public GET endpoint, and migration 039 for account_holder_name.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-07-26 11:04:26 +03:30
co-authored by Cursor
parent 426316d53c
commit 3faeb9bc0d
13 changed files with 1094 additions and 52 deletions
+16 -7
View File
@@ -154,6 +154,8 @@ Example super admin: `+989121111111` / `password`
| `020_store_items_and_variants.sql` | `store_items` + `store_item_variants` (replaces `product_variants`) |
| `036_invoices.sql` | Invoices, invoice items, invoice item templates + permissions |
| `037_invoice_name.sql` | Optional `invoices.name` |
| `038_invoice_templates.sql` | Full invoice templates + key points/accounts on invoices |
| `039_invoice_account_holder.sql` | `account_holder_name` on invoice / template accounts |
Docker mounts `./database/migrations` into Postgres init — migrations run automatically only on **first** volume creation. Use `migrate.sh` for subsequent migrations.
@@ -571,8 +573,10 @@ Super admins issue invoices **to** a business. Schema is ready for future busine
| Table | Purpose |
|-------|---------|
| `invoice_item_templates` | Predefined line items (`owner_scope` platform \| business) |
| `invoices` | Invoice header (`business_id` = billed party, optional `name`, `notes`, `status`) |
| `invoice_items` | Line items (title, duration, worktime, description, price, discounted_price) |
| `invoice_templates` | Full blueprints: name, top_text |
| `invoice_template_items` / `_key_points` / `_accounts` | Nested template content |
| `invoices` | Invoice header (`business_id` = billed party, optional `name`, `top_text`, `notes`, `invoice_template_id`, `status`) |
| `invoice_items` / `invoice_key_points` / `invoice_accounts` | Issued invoice nested content |
### API (super_admin only today)
@@ -580,16 +584,21 @@ Super admins issue invoices **to** a business. Schema is ready for future busine
|--------|------|
| GET/POST | `/invoice-item-templates` |
| PATCH/DELETE | `/invoice-item-templates/:templateId` |
| GET/POST | `/invoice-templates` |
| GET/PATCH/DELETE | `/invoice-templates/:templateId` |
| GET/POST | `/businesses/:businessId/invoices` |
| GET/PATCH/DELETE | `/businesses/:businessId/invoices/:invoiceId` |
| GET | `/public/invoices/:invoiceId` (no auth; issued/paid only) |
Auth: `JwtAuthGuard` + service `assertSuperAdmin`.
Auth (admin routes): `JwtAuthGuard` + service `assertSuperAdmin`.
Serialized platform invoices include `publicUrl`: `https://{INVOICE_PUBLIC_DOMAIN}/invoices/{id}` (default domain `meshkee.com`). Public HTML viewer is **not** implemented yet.
Serialized platform invoices include `publicUrl`: `https://{INVOICE_PUBLIC_DOMAIN}/invoices/{id}` (default `meshkee.com`), or `{INVOICE_PUBLIC_BASE_URL}/invoices/{id}` when set. Accounts include optional `accountHolderName`.
Public HTML viewer lives in the dashboards super-admin SPA (`/invoices/:id`); API serves JSON via `/public/invoices/:id`.
Permissions seeded for future business dashboard: `invoices.*`, `invoice_templates.*`.
Module: `src/invoices/`
Module: `src/invoices/` · Migrations: `036`, `037`, `038`, `039`
---
@@ -635,9 +644,9 @@ Follow the pattern in `CategoryVariationsService` / `CategoryTechnicalFormServic
| Purpose | Path |
|---------|------|
| Prisma schema | `prisma/schema.prisma` |
| Env template | `.env.example` (`INVOICE_PUBLIC_DOMAIN` for platform invoice links) |
| Env template | `.env.example` (`INVOICE_PUBLIC_DOMAIN` / optional `INVOICE_PUBLIC_BASE_URL`) |
| Invoices module | `src/invoices/` |
| Invoice migrations | `database/migrations/036_invoices.sql`, `037_invoice_name.sql` |
| Invoice migrations | `database/migrations/036_invoices.sql` `039_invoice_account_holder.sql` |
| Docker services | `docker-compose.yml` |
| Dev seed data | `database/seeds/001_sample_data.sql` |
| Postman | `postman/Meshkee-CMS-Auth.postman_collection.json` |
+4 -4
View File
@@ -74,9 +74,9 @@
<div class="panel">
<p style="margin:0 0 0.75rem"><strong>Global links</strong> (share these with designers &amp; AI tools):</p>
<a class="btn" href="./openapi.json">OpenAPI JSON</a>
<a class="btn secondary" href="./Meshkee-Website-API.postman_collection.json">Download Postman</a>
<a class="btn secondary" href="./AI_PROMPT.md">AI prompt</a>
<a class="btn" href="/docs/website/openapi.json">OpenAPI JSON</a>
<a class="btn secondary" href="/docs/website/Meshkee-Website-API.postman_collection.json">Download Postman</a>
<a class="btn secondary" href="/docs/website/AI_PROMPT.md">AI prompt</a>
</div>
<h2>Base URL</h2>
@@ -93,7 +93,7 @@
<h2>For a new website AI / designer</h2>
<ol>
<li>Open <a href="./AI_PROMPT.md">AI_PROMPT.md</a> and paste it into the AI chat.</li>
<li>Open <a href="/docs/website/AI_PROMPT.md">AI_PROMPT.md</a> and paste it into the AI chat.</li>
<li>Replace <code>&lt;WEBSITE_DOMAIN&gt;</code> with that sites apex.</li>
<li>Import the Postman collection (set <code>domain</code>, run Resolve tenant).</li>
<li>Or feed <code>openapi.json</code> to the AI / codegen tool.</li>