invoicesnest-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +291 -0
  2. package/build/api/business.api.js +15 -0
  3. package/build/api/client.api.js +9 -0
  4. package/build/api/client.js +42 -0
  5. package/build/api/dashboard.api.js +6 -0
  6. package/build/api/invoice.api.js +40 -0
  7. package/build/auth.js +10 -0
  8. package/build/config.js +11 -0
  9. package/build/index.js +12 -0
  10. package/build/schemas/client.schema.js +10 -0
  11. package/build/schemas/dashboard.schema.js +13 -0
  12. package/build/schemas/invoice.schema.js +43 -0
  13. package/build/server.js +235 -0
  14. package/build/tools/createClient.js +63 -0
  15. package/build/tools/createInvoice.js +165 -0
  16. package/build/tools/create_client.js +80 -0
  17. package/build/tools/create_invoice.js +145 -0
  18. package/build/tools/dashboard.js +46 -0
  19. package/build/tools/deleteInvoice.js +54 -0
  20. package/build/tools/delete_invoice.js +41 -0
  21. package/build/tools/duplicate_invoice.js +85 -0
  22. package/build/tools/explain_invoice.js +78 -0
  23. package/build/tools/generate_business_summary.js +94 -0
  24. package/build/tools/getBusinessContext.js +34 -0
  25. package/build/tools/getInvoice.js +55 -0
  26. package/build/tools/get_business_context.js +27 -0
  27. package/build/tools/get_invoice.js +41 -0
  28. package/build/tools/health_check.js +37 -0
  29. package/build/tools/list_capabilities.js +43 -0
  30. package/build/tools/payment_status.js +48 -0
  31. package/build/tools/recommend_payment_followup.js +49 -0
  32. package/build/tools/recurring.js +108 -0
  33. package/build/tools/recurring_invoice.js +100 -0
  34. package/build/tools/revenue.js +46 -0
  35. package/build/tools/searchClients.js +44 -0
  36. package/build/tools/search_clients.js +34 -0
  37. package/build/tools/search_everything.js +71 -0
  38. package/build/tools/search_invoices.js +41 -0
  39. package/build/tools/sendInvoice.js +54 -0
  40. package/build/tools/send_invoice.js +43 -0
  41. package/build/tools/updateInvoice.js +89 -0
  42. package/build/tools/update_invoice.js +74 -0
  43. package/build/tools/who_am_i.js +40 -0
  44. package/build/types/index.js +1 -0
  45. package/build/utils/currency.js +16 -0
  46. package/build/utils/dates.js +15 -0
  47. package/build/utils/errors.js +32 -0
  48. package/build/utils/formatter.js +8 -0
  49. package/build/utils/logger.js +17 -0
  50. package/package.json +59 -0
package/README.md ADDED
@@ -0,0 +1,291 @@
1
+ # InvoicesNest MCP Server
2
+
3
+ ![MCP Compatible](https://img.shields.io/badge/MCP-Compatible-blueviolet) ![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue) ![Node.js](https://img.shields.io/badge/Node.js-18%2B-green) ![Status](https://img.shields.io/badge/Status-Stable-brightgreen) ![License](https://img.shields.io/badge/License-Proprietary-red)
4
+
5
+ > **Version**: `1.1.0` | **Status**: `Stable` | **Transport**: `stdio` | **API Compatibility**: `InvoicesNest Backend >= v1.0`
6
+
7
+ Official Model Context Protocol (MCP) server for InvoicesNest.
8
+
9
+ Connect AI assistants such as Claude Desktop, Cursor, VS Code Copilot, and future MCP-compatible clients directly to your InvoicesNest workspace. The server exposes AI-native tools for invoices, clients, recurring billing, analytics, and business resources while keeping all business logic inside the InvoicesNest backend.
10
+
11
+ ---
12
+
13
+ ## Architecture Diagram
14
+
15
+ ```
16
+ [ Claude / Cursor / VS Code ]
17
+
18
+ │ Model Context Protocol (stdio)
19
+
20
+ [ InvoicesNest MCP Server ]
21
+
22
+ │ REST API calls (bypass tunnel headers)
23
+
24
+ [ InvoicesNest API Server ]
25
+
26
+ │ prisma
27
+
28
+ [ Database ]
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Design Philosophy
34
+
35
+ The MCP server is intentionally thin. It does not implement business rules or calculations directly. Instead, it exposes AI-friendly interfaces and validates request signatures. The InvoicesNest Backend remains the single source of truth. This architecture keeps AI clients lightweight while ensuring consistent business behavior across Web, Mobile, API, and MCP integrations.
36
+
37
+ ---
38
+
39
+ ## Compatible Clients
40
+
41
+ * **Claude Desktop**
42
+ * **Cursor IDE**
43
+ * **VS Code** (using MCP clients)
44
+ * **Continue.dev**
45
+ * **Cline**
46
+ * **Roo Code**
47
+
48
+ ---
49
+
50
+ ## Installation & Build
51
+
52
+ Ensure you have Node.js (v18+) and npm installed.
53
+
54
+ 1. Navigate into the `invoice-mcp` folder:
55
+ ```bash
56
+ cd invoice-mcp
57
+ ```
58
+ 2. Install dependencies:
59
+ ```bash
60
+ npm install
61
+ ```
62
+ 3. Build the TypeScript files:
63
+ ```bash
64
+ npm run build
65
+ ```
66
+ 4. Start the MCP server locally:
67
+ ```bash
68
+ npm start
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Project Tree
74
+
75
+ ```
76
+ invoice-mcp/
77
+ ├── build/ # Compiled JavaScript output
78
+ ├── src/
79
+ │ ├── api/ # Decoupled REST API wrappers
80
+ │ │ ├── business.api.ts
81
+ │ │ ├── client.api.ts
82
+ │ │ ├── dashboard.api.ts
83
+ │ │ └── invoice.api.ts
84
+ │ ├── schemas/ # Zod parameter validation schemas
85
+ │ │ ├── client.schema.ts
86
+ │ │ └── invoice.schema.ts
87
+ │ ├── tools/ # 21 MCP Tool handlers
88
+ │ ├── types/ # Shared TypeScript typings
89
+ │ ├── utils/ # Loggers, error formatters, and helpers
90
+ │ ├── config.ts # Central environment constants
91
+ │ ├── index.ts # Bootstraps Stdio server transport
92
+ │ ├── server.ts # Main MCP server routes registration
93
+ │ ├── prompts/ # Reserved for future MCP Prompt handlers
94
+ │ └── resources/ # Reserved for future MCP Resource handlers
95
+ ├── package.json
96
+ ├── tsconfig.json
97
+ └── README.md
98
+ ```
99
+
100
+ ---
101
+
102
+ ## Environment Variables
103
+
104
+ | Variable | Requirement | Default | Description |
105
+ | :--- | :--- | :--- | :--- |
106
+ | `INVOICESNEST_ACCESS_TOKEN` | **Required** | — | Your JWT account access token from settings dashboard. |
107
+ | `INVOICESNEST_BACKEND_URL` | **Required** | — | Base URL of your InvoicesNest API backend (e.g. `https://api.invoicesnest.com`). |
108
+ | `LOG_LEVEL` | Optional | `info` | Logging verbosity (`info`, `error`, `debug`). |
109
+ | `REQUEST_TIMEOUT` | Optional | `30000` | Backend API request timeout in milliseconds. |
110
+
111
+ ---
112
+
113
+ ## Exposed MCP Resources
114
+
115
+ The MCP Server exposes the following read-only context resources to your LLMs:
116
+
117
+ | Resource URI | MIME Type | Description |
118
+ | :--- | :--- | :--- |
119
+ | `invoicesnest://business/profile` | `application/json` | Active business profiles details (Name, address, email). |
120
+ | `invoicesnest://business/invoice-template` | `application/json` | Active template configurations. |
121
+ | `invoicesnest://business/payment-methods` | `application/json` | Allowed payment options. |
122
+ | `invoicesnest://business/branding` | `application/json` | Logo references and colors codes. |
123
+ | `invoicesnest://business/products` | `application/json` | Product inventory lists. |
124
+ | `invoicesnest://business/services` | `application/json` | Business services catalog. |
125
+ | `invoicesnest://business/tax-rules` | `application/json` | Default tax configurations. |
126
+ | `invoicesnest://business/payment-terms` | `text/plain` | Standard deadline payment guidelines. |
127
+ | `invoicesnest://business/currencies` | `application/json` | Supported currency codes and symbols. |
128
+ | `invoicesnest://business/company-settings` | `application/json` | Timezone metadata records. |
129
+ | `invoicesnest://business/number-format` | `text/plain` | Invoice serial numbering prefixes. |
130
+ | `invoicesnest://business/date-format` | `text/plain` | Selected date representation layout. |
131
+ | `invoicesnest://business/email-template` | `text/html` | HTML template layouts for client deliveries. |
132
+
133
+ ---
134
+
135
+ ## Exposed MCP Tools (21 total)
136
+
137
+ | # | Tool Name | Parameters | Description |
138
+ | :- | :--- | :--- | :--- |
139
+ | 1 | `health_check` | None | Diagnoses access token status and API connection health. |
140
+ | 2 | `who_am_i` | None | Returns active user session, workspaces list, and permission levels. |
141
+ | 3 | `list_capabilities` | None | Outlines active API capabilities and supported modules. |
142
+ | 4 | `get_business_context` | None | Retrieves active merchant profile, currency, and invoice prefix. |
143
+ | 5 | `search_everything` | `query` | Unified parallel search across Invoices, Clients, and Recurring profiles. |
144
+ | 6 | `explain_invoice` | `id` or `invoiceNumber` | Breaks down tax, discount, subtotal, grand total, and overdue status. |
145
+ | 7 | `recommend_payment_followup` | None | Returns overdue age data for LLM to formulate custom payment reminders. |
146
+ | 8 | `generate_business_summary` | None | Aggregates Revenue, Outstanding, MRR, Top Client, Collection Rate. |
147
+ | 9 | `create_invoice` | client details, items | Generates a new mathematically-validated invoice. |
148
+ | 10 | `get_invoice` | `id` or `invoiceNumber` | Reads complete invoice JSON metadata. |
149
+ | 11 | `search_invoices` | `query` | Searches invoices by number, client name, or email. |
150
+ | 12 | `update_invoice` | `id`, update fields | Performs partial field updates on an existing invoice. |
151
+ | 13 | `delete_invoice` | `id` or `invoiceNumber` | Deletes an invoice (subject to backend deletion policy). |
152
+ | 14 | `duplicate_invoice` | `id`, `newInvoiceNumber` | Clones an invoice and assigns the next serial number. |
153
+ | 15 | `create_client` | name, email, phone, address | Registers a new client CRM contact. |
154
+ | 16 | `search_clients` | `query` | Searches saved clients by name or email. |
155
+ | 17 | `recurring_invoice` | `action`, profile data | Manages recurring billing profiles (list, create, pause, resume, skip, delete). |
156
+ | 18 | `payment_status` | `status` | Filters invoices by PAID, PENDING, or OVERDUE. |
157
+ | 19 | `get_revenue_stats` | None | Calculates collected revenue and outstanding cashflow per currency. |
158
+ | 20 | `get_dashboard_summary` | None | Returns invoice count distributions across all statuses. |
159
+ | 21 | `send_invoice` | `id` or `invoiceNumber` | Emails PDF invoice directly to the client's address. |
160
+
161
+ ---
162
+
163
+ ## Developer Tool Schema Examples
164
+
165
+ ### 1. `create_invoice` Input Example
166
+ ```json
167
+ {
168
+ "clientName": "ABC Corp Ltd",
169
+ "clientEmail": "billing@abccorp.com",
170
+ "items": [
171
+ {
172
+ "description": "API Integration Consulting",
173
+ "quantity": 10,
174
+ "rate": 150
175
+ }
176
+ ],
177
+ "taxRate": 15,
178
+ "discountRate": 5,
179
+ "sendEmailToClient": true
180
+ }
181
+ ```
182
+
183
+ ### 2. `recurring_invoice` Input Example
184
+ ```json
185
+ {
186
+ "action": "create",
187
+ "createData": {
188
+ "clientName": "John Doe LLC",
189
+ "clientEmail": "john@doe.com",
190
+ "frequency": "MONTHLY",
191
+ "items": [
192
+ {
193
+ "description": "Monthly Retainer Services",
194
+ "quantity": 1,
195
+ "rate": 2000
196
+ }
197
+ ]
198
+ }
199
+ }
200
+ ```
201
+
202
+ ---
203
+
204
+ ## Interactive AI Prompt Library (55+ Real-World Prompt Scenarios)
205
+
206
+ ### Invoicing & Drafts
207
+ 1. *Create an invoice for ABC Ltd worth $450 with description "Consulting Work".*
208
+ 2. *Draft invoice for Ali Khan: 2 hours of Web Development at $100/hr, tax rate 15%.*
209
+ 3. *Duplicate invoice INV-0012 but set the status to draft.*
210
+ 4. *Update the due date of invoice INV-1002 to next Friday.*
211
+ 5. *Delete invoice with serial number INV-0056.*
212
+ 6. *Set the shipping cost of invoice INV-0089 to $25.*
213
+ 7. *Apply a 10% discount on invoice INV-0023 and recalculate.*
214
+ 8. *Add 3 items to invoice INV-1120: Item A for $100, Item B for $200, Item C for $300.*
215
+ 9. *Find my recent draft invoices.*
216
+ 10. *Get the exact JSON details of invoice INV-0011.*
217
+
218
+ ### Client Management & CRM
219
+ 11. *Create a client Ali Khan, email ali@example.com, address 123 Street Lahore.*
220
+ 12. *Search for a client named Smith.*
221
+ 13. *Find the contact details of customer XYZ Corp.*
222
+ 14. *Change the email address of client John Doe to john@newmail.com.*
223
+ 15. *Add phone number +92-300-1234567 to client Ali Ahmed.*
224
+ 16. *Register a new business client: name "Future Tech LLC", email "info@futuretech.co".*
225
+ 17. *Does client Ali already exist? Search the database.*
226
+ 18. *List all saved clients in my CRM.*
227
+ 19. *Update client address for 'Zubair Butt' to 'Main Boulevard Gulberg'.*
228
+ 20. *Find the client ID of 'Usman Ghani'.*
229
+
230
+ ### Payments & Overdue Tracking
231
+ 21. *Show unpaid invoices.*
232
+ 22. *List all overdue invoices.*
233
+ 23. *Which invoices are still pending payment?*
234
+ 24. *How many invoices were paid in USD?*
235
+ 25. *Check if invoice INV-0005 has been paid yet.*
236
+ 26. *List all PAID invoices.*
237
+ 27. *Recommend payment reminders based on currently overdue invoices.*
238
+ 28. *Draft a polite email to overdue client John Doe.*
239
+ 29. *Find all invoices with outstanding amount higher than $1000.*
240
+ 30. *List overdue invoices delayed by more than 30 days.*
241
+
242
+ ### Business Reports & Summaries
243
+ 31. *How is my business doing? Give me a full business summary.*
244
+ 32. *What is my collection rate this month?*
245
+ 33. *Calculate my total collected revenue and outstanding cashflow.*
246
+ 34. *Who is my top-paying client by cumulative paid totals?*
247
+ 35. *Who is my worst payer client in terms of overdue balances?*
248
+ 36. *What is my average invoice value?*
249
+ 37. *Estimate my Monthly Recurring Revenue (MRR) based on active profiles.*
250
+ 38. *Tell me how much revenue is pending in EUR.*
251
+ 39. *Explain invoice INV-1020: detail the tax portion and discount value.*
252
+ 40. *Summarize active invoice statistics.*
253
+
254
+ ### Recurring Invoices
255
+ 41. *List all active recurring billing profiles.*
256
+ 42. *Pause the recurring invoice for client Ali Khan.*
257
+ 43. *Resume the recurring profile with ID active-recur-id.*
258
+ 44. *Skip the next scheduled run for recurring invoice recurring-uuid-here.*
259
+ 45. *Trigger an immediate run of recurring invoice profile rec_9982.*
260
+ 46. *Delete the recurring billing template for Client John.*
261
+ 47. *Create a monthly recurring invoice for Client Zubair for $500, starting today.*
262
+ 48. *Show all paused recurring profiles.*
263
+ 49. *How much recurring revenue do we get from Client ABC LLC?*
264
+ 50. *What is the billing frequency of recurring profile rec-1020?*
265
+
266
+ ### Debugging & System Context
267
+ 51. *Run an MCP connection health check.*
268
+ 52. *Who am I logged in as? Show my workspace and permissions.*
269
+ 53. *What are the capabilities of the InvoicesNest API?*
270
+ 54. *Check if my JWT access token is valid.*
271
+ 55. *What is the default currency of my business context?*
272
+
273
+ ---
274
+
275
+ ## Public Release & Security Roadmap (v1.2)
276
+
277
+ For public directory listing and enterprise distribution, the authentication model will transition from JWT session cookies to:
278
+ 1. **Scoped MCP API Keys:** Dynamic creation of token prefix `inv_mcp_...` restricted to read-only or read-write permissions (e.g. `invoices:read`, `clients:write`).
279
+ 2. **OAuth2 Authorization Code Flow:** Enable direct browser-based oauth handshakes for external AI clients (ChatGPT GPTs store, Claude Workspaces) without manual credential mapping.
280
+
281
+ ---
282
+
283
+ ## License
284
+
285
+ Proprietary — Copyright © InvoicesNest. All rights reserved.
286
+
287
+ ---
288
+
289
+ ## Changelog
290
+
291
+ See [CHANGELOG.md](./CHANGELOG.md) for full release history.
@@ -0,0 +1,15 @@
1
+ import { callBackendApi } from "./client.js";
2
+ let cachedMetadata = null;
3
+ let cacheExpiry = 0;
4
+ const CACHE_TTL_MS = 10000; // 10 seconds cache TTL
5
+ export const BusinessApi = {
6
+ async getMetadata(forceRefresh = false) {
7
+ const now = Date.now();
8
+ if (!forceRefresh && cachedMetadata && now < cacheExpiry) {
9
+ return cachedMetadata;
10
+ }
11
+ cachedMetadata = await callBackendApi("/api/v1/invoices/metadata", "GET");
12
+ cacheExpiry = now + CACHE_TTL_MS;
13
+ return cachedMetadata;
14
+ }
15
+ };
@@ -0,0 +1,9 @@
1
+ import { callBackendApi } from "./client.js";
2
+ export const ClientApi = {
3
+ async list() {
4
+ return await callBackendApi("/api/v1/clients", "GET");
5
+ },
6
+ async create(payload) {
7
+ return await callBackendApi("/api/v1/clients", "POST", payload);
8
+ }
9
+ };
@@ -0,0 +1,42 @@
1
+ import { CONFIG } from "../config.js";
2
+ import { Logger } from "../utils/logger.js";
3
+ export async function callBackendApi(endpoint, method = "GET", body) {
4
+ const startTime = Date.now();
5
+ const token = CONFIG.ACCESS_TOKEN;
6
+ const backendUrl = CONFIG.BACKEND_URL;
7
+ const headers = {
8
+ "Authorization": `Bearer ${token}`,
9
+ "Content-Type": "application/json",
10
+ "bypass-tunnel-reminder": "true",
11
+ "ngrok-skip-browser-warning": "true"
12
+ };
13
+ const url = `${backendUrl.replace(/\/$/, "")}${endpoint}`;
14
+ Logger.info(`Initiating backend request: [${method}] ${url}`, body);
15
+ try {
16
+ const response = await fetch(url, {
17
+ method,
18
+ headers,
19
+ body: body ? JSON.stringify(body) : undefined
20
+ });
21
+ const duration = Date.now() - startTime;
22
+ Logger.info(`Backend response received in ${duration}ms: Status ${response.status}`);
23
+ const responseText = await response.text();
24
+ let responseData;
25
+ try {
26
+ responseData = JSON.parse(responseText);
27
+ }
28
+ catch (e) {
29
+ responseData = responseText;
30
+ }
31
+ if (!response.ok) {
32
+ const errorMsg = responseData?.message || responseData?.error || responseText || `HTTP error ${response.status}`;
33
+ throw new Error(errorMsg);
34
+ }
35
+ return responseData.data !== undefined ? responseData.data : responseData;
36
+ }
37
+ catch (err) {
38
+ const duration = Date.now() - startTime;
39
+ Logger.error(`Backend request failed after ${duration}ms`, err);
40
+ throw err;
41
+ }
42
+ }
@@ -0,0 +1,6 @@
1
+ import { callBackendApi } from "./client.js";
2
+ export const DashboardApi = {
3
+ async getInvoices() {
4
+ return await callBackendApi("/api/v1/invoices", "GET");
5
+ }
6
+ };
@@ -0,0 +1,40 @@
1
+ import { callBackendApi } from "./client.js";
2
+ export const InvoiceApi = {
3
+ async list() {
4
+ return await callBackendApi("/api/v1/invoices", "GET");
5
+ },
6
+ async get(id) {
7
+ return await callBackendApi(`/api/v1/invoices/${id}`, "GET");
8
+ },
9
+ async create(payload) {
10
+ return await callBackendApi("/api/v1/invoices", "POST", payload);
11
+ },
12
+ async update(id, payload) {
13
+ return await callBackendApi(`/api/v1/invoices/${id}`, "PUT", payload);
14
+ },
15
+ async delete(id) {
16
+ return await callBackendApi(`/api/v1/invoices/${id}`, "DELETE");
17
+ },
18
+ async sendEmail(id) {
19
+ return await callBackendApi(`/api/v1/invoices/${id}/resend-email`, "POST");
20
+ },
21
+ // Recurring endpoints
22
+ async listRecurring() {
23
+ return await callBackendApi("/api/v1/recurring", "GET");
24
+ },
25
+ async createRecurring(payload) {
26
+ return await callBackendApi("/api/v1/recurring", "POST", payload);
27
+ },
28
+ async updateRecurring(id, payload) {
29
+ return await callBackendApi(`/api/v1/recurring/${id}`, "PUT", payload);
30
+ },
31
+ async deleteRecurring(id) {
32
+ return await callBackendApi(`/api/v1/recurring/${id}`, "DELETE");
33
+ },
34
+ async runRecurring(id) {
35
+ return await callBackendApi(`/api/v1/recurring/${id}/run`, "POST");
36
+ },
37
+ async skipRecurring(id) {
38
+ return await callBackendApi(`/api/v1/recurring/${id}/skip-next`, "POST");
39
+ }
40
+ };
package/build/auth.js ADDED
@@ -0,0 +1,10 @@
1
+ import { CONFIG } from "./config.js";
2
+ export function getAccessToken() {
3
+ if (!CONFIG.ACCESS_TOKEN) {
4
+ throw new Error("Missing INVOICESNEST_ACCESS_TOKEN. Set it in your environment before starting the MCP server.");
5
+ }
6
+ return CONFIG.ACCESS_TOKEN;
7
+ }
8
+ export function getBackendUrl() {
9
+ return CONFIG.BACKEND_URL;
10
+ }
@@ -0,0 +1,11 @@
1
+ import dotenv from "dotenv";
2
+ dotenv.config();
3
+ export const CONFIG = {
4
+ VERSION: "v1",
5
+ API_COMPATIBILITY: "v1",
6
+ BACKEND_URL: process.env.INVOICESNEST_BACKEND_URL || "https://abed-223-123-76-202.ngrok-free.app",
7
+ ACCESS_TOKEN: process.env.INVOICESNEST_ACCESS_TOKEN || "",
8
+ };
9
+ if (!CONFIG.ACCESS_TOKEN) {
10
+ console.error("WARNING: INVOICESNEST_ACCESS_TOKEN is not configured. MCP requests will fail until authorized.");
11
+ }
package/build/index.js ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { server } from "./server.js";
4
+ async function main() {
5
+ const transport = new StdioServerTransport();
6
+ await server.connect(transport);
7
+ console.error("InvoicesNest Model Context Protocol (MCP) server running on stdio transport");
8
+ }
9
+ main().catch((error) => {
10
+ console.error("MCP Server lifecycle crash:", error);
11
+ process.exit(1);
12
+ });
@@ -0,0 +1,10 @@
1
+ import { z } from "zod";
2
+ export const createClientSchema = z.object({
3
+ name: z.string().min(1, "Client name is required"),
4
+ email: z.string().email("Valid email is required"),
5
+ phone: z.string().optional(),
6
+ address: z.string().optional(),
7
+ taxId: z.string().optional(),
8
+ notes: z.string().optional(),
9
+ businessId: z.string().optional()
10
+ });
@@ -0,0 +1,13 @@
1
+ import { z } from "zod";
2
+ export const getDashboardSummarySchema = z.object({});
3
+ export const getRevenueStatsSchema = z.object({});
4
+ export const paymentStatusSchema = z.object({
5
+ status: z.enum(["PAID", "PENDING", "OVERDUE"])
6
+ });
7
+ export const sendInvoiceSchema = z.object({
8
+ id: z.string().optional(),
9
+ invoiceNumber: z.string().optional()
10
+ });
11
+ export const searchInvoicesSchema = z.object({
12
+ query: z.string().optional()
13
+ });
@@ -0,0 +1,43 @@
1
+ import { z } from "zod";
2
+ export const createInvoiceSchema = z.object({
3
+ clientName: z.string().min(1, "Client name is required"),
4
+ clientEmail: z.string().email("Valid email is required").optional().or(z.literal("")),
5
+ clientAddress: z.string().optional(),
6
+ clientPhone: z.string().optional(),
7
+ invoiceNumber: z.string().optional(),
8
+ invoiceDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be YYYY-MM-DD").optional(),
9
+ dueDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be YYYY-MM-DD").optional().or(z.literal("")),
10
+ currency: z.string().length(3, "Currency code must be 3 characters").optional(),
11
+ taxRate: z.number().min(0, "Tax rate cannot be negative").max(100, "Tax rate cannot exceed 100").optional(),
12
+ discountRate: z.number().min(0, "Discount rate cannot be negative").max(100, "Discount rate cannot exceed 100").optional(),
13
+ shipping: z.number().min(0, "Shipping cost cannot be negative").optional(),
14
+ amountPaid: z.number().min(0, "Amount paid cannot be negative").optional(),
15
+ notes: z.string().optional(),
16
+ terms: z.string().optional(),
17
+ status: z.enum(["DRAFT", "SENT", "PAID"]).optional(),
18
+ sendEmailToClient: z.boolean().optional(),
19
+ businessId: z.string().optional(),
20
+ items: z.array(z.object({
21
+ description: z.string().min(1, "Description is required"),
22
+ quantity: z.number().min(0.01, "Quantity must be at least 0.01").optional(),
23
+ rate: z.number().min(0, "Rate cannot be negative").optional()
24
+ })).min(1, "At least one item is required")
25
+ });
26
+ export const updateInvoiceSchema = z.object({
27
+ id: z.string().optional(),
28
+ invoiceNumber: z.string().optional(),
29
+ updateData: z.object({
30
+ clientName: z.string().optional(),
31
+ clientEmail: z.string().email().optional().or(z.literal("")),
32
+ clientAddress: z.string().optional(),
33
+ clientPhone: z.string().optional(),
34
+ status: z.enum(["DRAFT", "SENT", "PAID", "OVERDUE"]).optional(),
35
+ notes: z.string().optional(),
36
+ terms: z.string().optional(),
37
+ dueDate: z.string().optional().or(z.literal("")),
38
+ taxRate: z.number().optional(),
39
+ discountRate: z.number().optional(),
40
+ shipping: z.number().optional(),
41
+ amountPaid: z.number().optional()
42
+ })
43
+ });