533 lines
28 KiB
Markdown
533 lines
28 KiB
Markdown
# Agent Prompts — Swish Auto Care GMS
|
||
## All Prompts for Claude Opus 4 in Claude Code (Antigravity)
|
||
|
||
> **How to use this file:**
|
||
> Copy each prompt exactly as written into Claude Code, one phase at a time.
|
||
> Wait for the phase to complete and be verified before moving to the next prompt.
|
||
> All context files should be in the same project folder so the agent can reference them.
|
||
|
||
---
|
||
|
||
## INITIAL SETUP PROMPT (Run This First — Before Any Phase)
|
||
|
||
```
|
||
You are building the Swish Auto Care Garage Management System (GMS) from scratch.
|
||
|
||
Before you write any code, read these context files in this exact order:
|
||
1. 00_PROJECT_OVERVIEW.md — master context and what you're building
|
||
2. 01_DATABASE_SCHEMA.md — all MySQL tables and relationships
|
||
3. 02_API_REFERENCE.md — all backend API routes
|
||
4. 03_FRONTEND_PAGES.md — all frontend pages and their behavior
|
||
5. 04_BUSINESS_LOGIC.md — rules, calculations, and validations
|
||
6. 05_IMPLEMENTATION_PLAN.md — the build order and phases
|
||
|
||
After reading all 6 files, confirm you understand the full system by giving me:
|
||
- A one-paragraph summary of what Swish Auto Care GMS does
|
||
- The tech stack you will use (exact packages)
|
||
- The 10 modules you will build (M1–M10)
|
||
- Confirmation that you understand the 6-phase build order
|
||
|
||
Do NOT write any code yet. Just confirm your understanding.
|
||
```
|
||
|
||
---
|
||
|
||
## PHASE 1 PROMPT — Foundation
|
||
|
||
```
|
||
You are building the Swish Auto Care GMS. Read 00_PROJECT_OVERVIEW.md, 01_DATABASE_SCHEMA.md, 02_API_REFERENCE.md, and 04_BUSINESS_LOGIC.md before starting.
|
||
|
||
Build Phase 1 — Foundation. Do all of these tasks in order:
|
||
|
||
BACKEND:
|
||
1. Create the folder structure: swish-gms/backend/src/config/, middleware/, routes/
|
||
2. Initialize npm in backend/ and install: express mysql2 jsonwebtoken bcryptjs dotenv cors
|
||
3. Install dev dependency: nodemon
|
||
4. Create backend/.env with:
|
||
PORT=5000, DB_HOST=localhost, DB_USER=root, DB_PASS=root, DB_NAME=swish_gms, JWT_SECRET=swishgms_jwt_secret_2026_local
|
||
5. Create backend/src/config/db.js — MySQL connection pool using mysql2/promise with promise wrapper
|
||
6. Create backend/src/config/schema.sql — complete SQL with all 8 tables (from 01_DATABASE_SCHEMA.md). Include CREATE DATABASE IF NOT EXISTS.
|
||
7. Create backend/src/config/seed.js — a runnable Node.js script that:
|
||
a. Hashes the password 'swish@2024' using bcryptjs
|
||
b. Inserts admin user (username: admin)
|
||
c. Inserts 4 sample staff members (from seed data in 01_DATABASE_SCHEMA.md)
|
||
d. Inserts 5 sample parts (from seed data in 01_DATABASE_SCHEMA.md)
|
||
e. Prints "Seed complete" when done
|
||
8. Create backend/src/middleware/auth.js — JWT verify middleware (pattern in 04_BUSINESS_LOGIC.md)
|
||
9. Create backend/src/routes/auth.js — POST /login (validate, return JWT + user) and GET /me (protected)
|
||
10. Create backend/src/server.js — Express app with CORS (origin: http://localhost:5173), JSON body parser, /api/auth route mounted
|
||
11. Add scripts to package.json: "dev": "nodemon src/server.js", "seed": "node src/config/seed.js"
|
||
|
||
FRONTEND:
|
||
12. Create frontend/ using: npm create vite@latest frontend -- --template react-ts
|
||
13. Install: react-router-dom axios
|
||
14. Create frontend/src/api/axios.ts — Axios instance (baseURL: http://localhost:5000/api) with request interceptor for JWT and response interceptor for 401 auto-logout (pattern in 03_FRONTEND_PAGES.md)
|
||
15. Create frontend/src/context/AuthContext.tsx — AuthContext with user, token, login(), logout(), isAuthenticated (store token in localStorage key 'gms_token')
|
||
16. Create frontend/src/pages/Login.tsx — full login form page (centered card, username + password fields, submit calls POST /api/auth/login, stores JWT, redirects to /dashboard)
|
||
17. Create frontend/src/components/Layout/Sidebar.tsx — sidebar with all 12 nav links listed in 03_FRONTEND_PAGES.md
|
||
18. Create frontend/src/components/Layout/TopBar.tsx — shows "Swish Auto Care GMS", current date in DD/MM/YYYY, "Admin" label, Logout button
|
||
19. Create frontend/src/components/Layout/Layout.tsx — wrapper that renders Sidebar + TopBar + main content area
|
||
20. Create placeholder page files (just return <div>PageName Page</div>) for: Dashboard, JobCards, JobCardNew, StatusBoard, Staff, Attendance, Salary, Parts, PartsSales, CashLedger, Accounts, DailyReport, Exports
|
||
21. Create frontend/src/App.tsx — React Router setup with: /login (public), all other routes wrapped in ProtectedRoute (redirects to /login if not authenticated), / redirects to /dashboard
|
||
22. Verify frontend/src/main.tsx wraps App in AuthContext provider
|
||
|
||
TESTING INSTRUCTIONS I WILL RUN:
|
||
- Terminal 1: cd backend && npm run dev → should print "Server running on port 5000"
|
||
- MySQL: Run schema.sql, then npm run seed → "Seed complete"
|
||
- Test login: curl -X POST http://localhost:5000/api/auth/login -H "Content-Type: application/json" -d '{"username":"admin","password":"swish@2024"}' → should return token
|
||
- Terminal 2: cd frontend && npm run dev → open http://localhost:5173
|
||
- Login page should show → login should work → sidebar should appear
|
||
|
||
Do not move on to Phase 2 tasks. Only deliver Phase 1.
|
||
```
|
||
|
||
---
|
||
|
||
## PHASE 2 PROMPT — Job Cards & Status Board
|
||
|
||
```
|
||
Phase 1 is complete and working. Now build Phase 2 — Job Cards & Status Board.
|
||
|
||
Read 02_API_REFERENCE.md (Job Card Routes section) and 03_FRONTEND_PAGES.md (Pages 2-5) and 04_BUSINESS_LOGIC.md (Section 1) before starting.
|
||
|
||
BACKEND:
|
||
1. Create backend/src/routes/jobCards.js with these routes (all protected by auth middleware):
|
||
- GET /api/job-cards — list with filters: status, date (YYYY-MM-DD), reg_no, page, limit. Join with staff table to get assigned_staff_name. Default: today's jobs.
|
||
- POST /api/job-cards — create new job card. Auto-generate job_no using the SAC-YYYYMMDD-SEQ format (see 04_BUSINESS_LOGIC.md Section 1). Validate required fields based on job_type.
|
||
- GET /api/job-cards/:id — single job card with staff name
|
||
- PUT /api/job-cards/:id — update fields only if status = 'active'
|
||
- POST /api/job-cards/:id/close — mark done: require final_amount > 0 and payment_mode, set status='done', closed_at=NOW(), reject if already done
|
||
|
||
2. Create backend/src/routes/dashboard.js (protected):
|
||
- GET /api/dashboard/today — return: active_jobs (count where status='active' and DATE(job_date)=today), completed_jobs (count where status='done' and DATE(closed_at)=today), today_revenue (SUM of final_amount where status='done' and DATE(closed_at)=today), cash_balance (set to 0 for now — will add later), staff_present (set to 0 for now), date (formatted DD/MM/YYYY)
|
||
|
||
3. Mount both routes in server.js
|
||
|
||
FRONTEND:
|
||
4. Create frontend/src/components/shared/Badge.tsx — takes status prop ('active'|'done'|'full'|'wash'|'in'|'out'), returns colored pill span. Colors: active=amber, done=green, full=blue, wash=teal, in=green, out=red.
|
||
|
||
5. Create frontend/src/components/shared/Modal.tsx — overlay modal with title, close button (X), and children slot. Click outside to close.
|
||
|
||
6. Build frontend/src/pages/Dashboard.tsx:
|
||
- Calls GET /api/dashboard/today on load
|
||
- Shows 6 widget cards: Active Jobs, Completed Jobs, Today's Revenue (₹ format), Cash Balance (₹ format), Staff Present, Quick Actions
|
||
- Quick actions card has 3 buttons: "New Job Card" (→ /job-cards/new), "Mark Attendance" (→ /attendance), "Daily Report" (→ /daily-report)
|
||
- Show loading skeleton while fetching
|
||
|
||
7. Build frontend/src/pages/JobCards.tsx:
|
||
- Calls GET /api/job-cards on load and on filter change
|
||
- Search bar for reg_no (debounced 500ms)
|
||
- Status dropdown filter (All / Active / Done)
|
||
- Date picker (default today)
|
||
- Table with columns: Job No, Type (Badge), Reg No, Car, Owner, Service, Staff, Amount (show final if done, estimated if active), Status (Badge), Date, Actions
|
||
- Actions: View icon (expand row or simple alert for now), Edit icon (only if active — opens edit modal), Close icon (only if active — opens Close Job modal)
|
||
- Close Job modal: Final Amount input (₹), Payment Mode dropdown (Cash/UPI/Card), "Mark as Done" button. On submit: POST /api/job-cards/:id/close, refresh list, show success toast
|
||
- "+ New Job Card" button top right → navigate to /job-cards/new
|
||
|
||
8. Build frontend/src/pages/JobCardNew.tsx:
|
||
- Toggle at top: "Full Service Job" | "Quick Wash Job" — switches which form renders
|
||
- Full job form fields (all from 03_FRONTEND_PAGES.md Page 4): reg_no*, car_name*, owner_name*, mobile_no*, service_type* (dropdown with options from PRD), assigned_staff_id* (dropdown — fetch from GET /api/staff?is_active=1), estimated_amount, notes
|
||
- Quick wash form fields: reg_no*, car_name*, mobile_no (optional), service_type* (Basic Wash/Premium Wash/Interior Clean), assigned_staff_id*, estimated_amount*
|
||
- On submit: POST /api/job-cards, show success toast with job_no, navigate to /job-cards
|
||
- Cancel button → navigate to /job-cards
|
||
|
||
9. Build frontend/src/pages/StatusBoard.tsx:
|
||
- Two columns side by side: ACTIVE (amber header) | DONE (green header)
|
||
- Fetch GET /api/job-cards with no date filter and show all active + today's done
|
||
- Each card shows: job_no, reg_no — car_name, service_type | assigned_staff_name, amount, time
|
||
- Active cards have "Mark Done" button → same Close Job modal as JobCards.tsx
|
||
- Card counts in column headers: "ACTIVE (4)" | "DONE (7)"
|
||
|
||
10. Create simple toast notification system (can be a simple fixed-bottom-right div with auto-dismiss):
|
||
frontend/src/components/shared/Toast.tsx
|
||
|
||
TESTING I WILL RUN:
|
||
- Create a Full Job card, verify job_no is SAC-[today]-001
|
||
- Create a Quick Wash job card
|
||
- See both in job cards list
|
||
- Mark one as done, verify status changes to Done with final_amount
|
||
- Dashboard shows updated counts
|
||
- Status board shows Active and Done columns
|
||
```
|
||
|
||
---
|
||
|
||
## PHASE 3 PROMPT — Staff, Attendance & Salary
|
||
|
||
```
|
||
Phase 2 is complete. Build Phase 3 — Staff Management, Attendance, and Salary.
|
||
|
||
Read 02_API_REFERENCE.md (Staff, Attendance, Salary sections) and 03_FRONTEND_PAGES.md (Pages 6-8) and 04_BUSINESS_LOGIC.md (Sections 2-4).
|
||
|
||
BACKEND:
|
||
1. Create backend/src/routes/staff.js (all protected):
|
||
- GET /api/staff — list all staff, filter by is_active query param
|
||
- POST /api/staff — add staff, auto-generate staff_code (pattern in 04_BUSINESS_LOGIC.md Section 2)
|
||
- PUT /api/staff/:id — update staff details
|
||
- PATCH /api/staff/:id/toggle — flip is_active (1→0 or 0→1)
|
||
|
||
2. Create backend/src/routes/attendance.js (all protected):
|
||
- GET /api/attendance?date=YYYY-MM-DD — return all active staff with their attendance status for the date (LEFT JOIN attendance ON staff_id and date). Null status if not marked.
|
||
- POST /api/attendance/bulk — save array of {staff_id, status} for a given date. Use INSERT ... ON DUPLICATE KEY UPDATE (upsert). See 04_BUSINESS_LOGIC.md Section 3.
|
||
- GET /api/attendance/summary/:staffId?month=3&year=2026 — count present/absent/half for the month, return with day-by-day records
|
||
|
||
3. Create backend/src/routes/salary.js (all protected):
|
||
- GET /api/salary — list payments, filter by staff_id and/or payment_month
|
||
- POST /api/salary — create payment record (all fields from schema)
|
||
- GET /api/salary/calculate/:staffId?month=3&year=2026 — compute salary using formula: (monthly_salary / 26) × effectiveDays where effectiveDays = present + (half × 0.5). See 04_BUSINESS_LOGIC.md Section 4.
|
||
|
||
4. Update dashboard route: update staff_present to query COUNT from attendance where attendance_date = today AND status = 'present'
|
||
|
||
5. Mount all routes in server.js
|
||
|
||
FRONTEND:
|
||
6. Build frontend/src/pages/Staff.tsx:
|
||
- Table: Staff Code, Name, Role, Mobile, Joining Date, Salary (₹ format), Status (Active/Inactive toggle), Actions (Edit)
|
||
- "+ Add Staff" button → opens Add Staff modal
|
||
- Search by name (filter on frontend)
|
||
- Add/Edit Staff modal fields: Full Name*, Role*, Mobile No., Date of Joining, Monthly Salary ₹*, Active toggle
|
||
- Toggle active: calls PATCH /api/staff/:id/toggle, refreshes list
|
||
|
||
7. Build frontend/src/pages/Attendance.tsx:
|
||
- Date picker at top (default today, formatted DD/MM/YYYY)
|
||
- On date change: fetch GET /api/attendance?date=YYYY-MM-DD
|
||
- Attendance grid: each row = staff member with 3 radio buttons (Present / Absent / Half Day)
|
||
- Pre-fill radio from fetched status (null = nothing selected yet)
|
||
- "Save Attendance" button → POST /api/attendance/bulk with all rows
|
||
- Show success toast "Attendance saved for DD/MM/YYYY"
|
||
- Below table: clickable "View Monthly Summary" per staff → modal showing month grid and counts
|
||
|
||
8. Build frontend/src/pages/Salary.tsx — two sections:
|
||
|
||
Section A (New Payment form, top):
|
||
- Select Staff * (dropdown, active staff)
|
||
- Payment Month * (text input e.g. "March 2026")
|
||
- "Calculate" button → calls GET /api/salary/calculate/:id?month=&year= → fills Days Present and Calculated Salary (read-only display)
|
||
- Payment Amount ₹ * (pre-filled from calculated, editable override)
|
||
- Payment Type * (Full Salary / Advance / Bonus / Deduction)
|
||
- Payment Mode * (Cash / Bank / UPI)
|
||
- Notes (optional)
|
||
- "Record Payment" button → POST /api/salary, show toast, reset form
|
||
|
||
Section B (History table, below):
|
||
- Filter by Staff (dropdown) and Month (text)
|
||
- Table: Date | Staff | Month | Type | Mode | Amount | Notes
|
||
|
||
TESTING I WILL RUN:
|
||
- Add a new staff member, verify staff_code auto-generates
|
||
- Mark today's attendance for all staff, save, reload — verify it persists
|
||
- Calculate salary for a staff member (March 2026), verify formula: monthly_salary/26 × days
|
||
- Record a salary payment, verify it appears in history
|
||
- Dashboard staff_present count updates
|
||
```
|
||
|
||
---
|
||
|
||
## PHASE 4 PROMPT — Parts, Sales & Cash Ledger
|
||
|
||
```
|
||
Phase 3 is complete. Build Phase 4 — Parts Inventory, Parts Sales POS, and Cash Ledger.
|
||
|
||
Read 02_API_REFERENCE.md (Parts, Parts Sales, Cash Ledger sections) and 03_FRONTEND_PAGES.md (Pages 9-11) and 04_BUSINESS_LOGIC.md (Sections 5-6).
|
||
|
||
BACKEND:
|
||
1. Create backend/src/routes/parts.js (all protected):
|
||
- GET /api/parts — list all parts. Include is_low flag (stock_qty <= low_stock_alert). Filter: ?category=&low_stock=true
|
||
- POST /api/parts — add part, auto-generate part_code (pattern in 04_BUSINESS_LOGIC.md Section 5)
|
||
- PUT /api/parts/:id — update part details
|
||
- PATCH /api/parts/:id/stock — manual stock adjustment: UPDATE parts SET stock_qty = stock_qty + ? WHERE id = ?
|
||
|
||
2. Create backend/src/routes/partsSales.js (all protected):
|
||
- GET /api/parts-sales — list sales, join with parts for name. Filter by date.
|
||
- POST /api/parts-sales — CRITICAL:
|
||
a. Validate quantity > 0
|
||
b. Run: UPDATE parts SET stock_qty = stock_qty - ? WHERE id = ? AND stock_qty >= ?
|
||
c. Check affectedRows — if 0, return 400 "Insufficient stock"
|
||
d. If stock deducted, insert into parts_sales
|
||
e. Return sale record with part name
|
||
|
||
3. Create backend/src/routes/cashLedger.js (all protected):
|
||
- GET /api/cash-ledger — list entries. Filter by from/to date and type.
|
||
- POST /api/cash-ledger — create entry. Validate: description is non-empty after trim, amount > 0, entry_type is 'in' or 'out'.
|
||
|
||
4. Update dashboard route: update today_revenue to include BOTH job revenue AND parts revenue:
|
||
SELECT (job_revenue + parts_revenue) as today_revenue where both are summed for today
|
||
|
||
5. Mount all routes in server.js
|
||
|
||
FRONTEND:
|
||
6. Build frontend/src/pages/Parts.tsx:
|
||
- Table: Part Code, Name, Category, Unit, Buy Price (₹), Sell Price (₹), Stock Qty, Low Stock (red badge if is_low), Actions
|
||
- "+ Add Part" button → opens Add Part modal
|
||
- Filter by Category dropdown, "Show Low Stock Only" toggle
|
||
- Search by name
|
||
- Restock modal: Adjustment quantity (positive integer), confirm button → calls PATCH /api/parts/:id/stock
|
||
- Add/Edit Part modal: all fields from parts table
|
||
|
||
7. Build frontend/src/pages/PartsSales.tsx:
|
||
- Date filter (default today)
|
||
- Sales table: Date, Part Name, Qty, Unit Price (₹), Total (₹), Customer, Payment Mode, Job Card (if linked)
|
||
- "+ Record Sale" button → New Sale modal:
|
||
a. Select Part* (searchable dropdown — shows "Ceramic Coat 9H (Stock: 15)")
|
||
b. Link to Job Card? (optional dropdown — show recent active + done job cards)
|
||
c. Quantity * (number input — on blur, validate against available stock shown)
|
||
d. Unit Price ₹ (auto-fills from part.selling_price, editable)
|
||
e. Total Amount ₹ (auto-calculated = qty × unit_price, read-only)
|
||
f. Customer Name (optional)
|
||
g. Payment Mode * (Cash / UPI / Card)
|
||
h. "Record Sale" button → POST /api/parts-sales. If 400 insufficient stock, show error in modal. On success: toast, close modal, refresh table.
|
||
|
||
8. Build frontend/src/pages/CashLedger.tsx:
|
||
- Date range filter (from/to, default today to today)
|
||
- Ledger table: Date, Type (IN/OUT Badge), Category, Description, Amount (₹)
|
||
- Two buttons top right: "+ Cash In" and "+ Cash Out"
|
||
- Both open same modal (pre-selects type based on which button):
|
||
a. Entry Type (pre-filled, not editable)
|
||
b. Amount ₹ *
|
||
c. Category * (dropdown: Utilities, Supplies, Advance, Refund, Other)
|
||
d. Description * (mandatory text)
|
||
e. Date & Time (auto-filled with now, editable)
|
||
f. "Save Entry" button
|
||
|
||
TESTING I WILL RUN:
|
||
- Add a new part, verify part_code auto-generates
|
||
- Record a parts sale: select part, quantity 3, verify stock decreases by 3
|
||
- Try to sell more than available stock — verify error message shows
|
||
- Enter a Cash In entry, verify it appears in table
|
||
- Enter a Cash Out entry (utility bill), verify it appears
|
||
- Dashboard today_revenue now includes parts sales
|
||
```
|
||
|
||
---
|
||
|
||
## PHASE 5 PROMPT — Accounts, Reports & Exports
|
||
|
||
```
|
||
Phase 4 is complete. Build Phase 5 — Accounts, Daily Report, and Excel Exports.
|
||
|
||
Read 02_API_REFERENCE.md (Accounts, Reports, Exports sections), 03_FRONTEND_PAGES.md (Pages 12-14), and 04_BUSINESS_LOGIC.md (Sections 7-9).
|
||
|
||
BACKEND:
|
||
1. Install SheetJS: npm install xlsx (in backend/)
|
||
|
||
2. Create backend/src/utils/excel.js — helper function createExcelResponse(res, filename, sheetsData) that:
|
||
- Takes sheetsData as array of {sheetName, data (array of objects)}
|
||
- Creates XLSX workbook with XLSX.utils.book_new()
|
||
- For each sheet: XLSX.utils.json_to_sheet(data) → book_append_sheet
|
||
- Writes buffer: XLSX.write(wb, { type: 'buffer', bookType: 'xlsx' })
|
||
- Sets Content-Type and Content-Disposition headers
|
||
- Sends buffer response
|
||
|
||
3. Create backend/src/routes/accounts.js (protected):
|
||
- GET /api/accounts/summary?from=YYYY-MM-DD&to=YYYY-MM-DD (default: today to today):
|
||
Run 5 separate SQL queries (see 04_BUSINESS_LOGIC.md Section 7) for:
|
||
job_revenue, parts_revenue, cash_in_other, staff_payments, cash_out_other
|
||
Return structured JSON with income object, expense object, net_balance
|
||
- GET /api/accounts/transactions?from=&to= — unified list of all transactions:
|
||
UNION of completed jobs (type:'job'), parts sales (type:'parts'), cash_in (type:'cash_in'), cash_out (type:'cash_out'), salary payments (type:'salary')
|
||
Each row: date, description, amount, type, reference (job_no or part_code etc.)
|
||
ORDER BY date DESC
|
||
|
||
4. Create backend/src/routes/reports.js (protected):
|
||
- GET /api/reports/daily?date=YYYY-MM-DD — return JSON with all 6 sections of the daily report data
|
||
- GET /api/reports/daily/download?date=YYYY-MM-DD — generate and stream Excel file:
|
||
Use createExcelResponse with 6 sheets per 04_BUSINESS_LOGIC.md Section 8
|
||
Filename format: SwishGMS_DailyReport_DD-MM-YYYY.xlsx
|
||
|
||
5. Create backend/src/routes/exports.js (protected):
|
||
- GET /api/exports/job-cards?from=&to= — all job cards as xlsx (join staff name)
|
||
Columns: Job No, Type, Reg No, Car Name, Owner, Mobile, Service, Staff, Estimated ₹, Final ₹, Payment Mode, Status, Job Date, Closed At
|
||
- GET /api/exports/staff-attendance?month=&year= — two sheets:
|
||
Sheet 1: Staff Master (all staff columns)
|
||
Sheet 2: Attendance (staff_name, date, status) for the given month
|
||
- GET /api/exports/parts-inventory — all parts as xlsx
|
||
Columns: Part Code, Name, Category, Unit, Buy Price, Sell Price, Stock Qty, Low Stock Alert
|
||
- GET /api/exports/accounts?from=&to= — accounts ledger as xlsx
|
||
Same columns as accounts/transactions response, formatted nicely
|
||
|
||
6. Update dashboard route: update cash_balance to sum all cash flows for today:
|
||
cash_balance = job_revenue + parts_revenue + cash_in_other - staff_payments - cash_out_other
|
||
|
||
7. Mount all routes in server.js
|
||
|
||
FRONTEND:
|
||
8. Build frontend/src/pages/Accounts.tsx:
|
||
- Date range filter at top with presets: "Today" | "This Week" | "This Month" | "Custom"
|
||
- 3 summary cards: Total Income (₹, green) | Total Expense (₹, red) | Net Balance (₹, blue)
|
||
- Two breakdown tables side by side:
|
||
Income: Job Revenue | Parts Sales | Cash In (Other) | Total
|
||
Expenses: Staff Payments | Cash Out (Other) | Total
|
||
- "All Transactions" tab below showing unified list from /api/accounts/transactions
|
||
Table: Date, Type (badge), Description, Amount (₹), Reference
|
||
|
||
9. Build frontend/src/pages/DailyReport.tsx:
|
||
- Date picker (default today)
|
||
- On date change: fetch GET /api/reports/daily?date=YYYY-MM-DD
|
||
- Render on-screen preview:
|
||
a. Header card: "Swish Auto Care — Daily Report" | date | Total Income | Total Expense | Net Balance
|
||
b. Section tables: Completed Jobs, Parts Sales, Cash In, Cash Out, Staff Payments
|
||
c. Day Totals row at bottom
|
||
- "Download Excel" button (primary, prominent):
|
||
Calls downloadExcel() helper (see 03_FRONTEND_PAGES.md Excel Download Pattern) with /api/reports/daily/download?date= and filename SwishGMS_DailyReport_DD-MM-YYYY.xlsx
|
||
|
||
10. Build frontend/src/pages/Exports.tsx:
|
||
- 4 export cards in a 2×2 grid
|
||
- Card 1 — Job Cards: From Date + To Date pickers + "Download xlsx" button
|
||
- Card 2 — Staff & Attendance: Month selector (1-12) + Year (2026) + "Download xlsx" button
|
||
- Card 3 — Parts Inventory: Just a "Download xlsx" button (no date filter needed)
|
||
- Card 4 — Accounts Ledger: From Date + To Date pickers + "Download xlsx" button
|
||
- Each download button uses the downloadExcel() helper with responseType: 'blob' and triggers browser file save
|
||
- Show loading state on button while downloading (spinner, disable button)
|
||
|
||
11. Create frontend/src/utils/download.ts with the downloadExcel helper function:
|
||
```ts
|
||
export async function downloadExcel(api: AxiosInstance, url: string, filename: string, params?: object) {
|
||
const response = await api.get(url, { params, responseType: 'blob' });
|
||
const blob = new Blob([response.data], {
|
||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||
});
|
||
const link = document.createElement('a');
|
||
link.href = URL.createObjectURL(blob);
|
||
link.download = filename;
|
||
document.body.appendChild(link);
|
||
link.click();
|
||
document.body.removeChild(link);
|
||
URL.revokeObjectURL(link.href);
|
||
}
|
||
```
|
||
|
||
TESTING I WILL RUN:
|
||
- Accounts page loads with today's summary (income, expense, balance)
|
||
- Change date range to "This Month" — totals update
|
||
- Daily Report page shows all sections for today
|
||
- Download daily report — verify it opens in Excel with correct data
|
||
- All 4 Export buttons produce downloadable .xlsx files with correct data
|
||
- Dashboard cash_balance now shows a real number
|
||
```
|
||
|
||
---
|
||
|
||
## PHASE 6 PROMPT — Polish, Seed Data & Final Testing
|
||
|
||
```
|
||
Phase 5 is complete. Build Phase 6 — Final Polish, Seed Data, and Complete the Demo.
|
||
|
||
SEED DATA (create backend/src/config/fullSeed.js):
|
||
Create a comprehensive seed that inserts:
|
||
1. Admin user (username: admin, password: swish@2024, bcrypt hashed)
|
||
2. 4 staff members (already seeded in Phase 1, skip if exists)
|
||
3. 5 parts (already seeded, skip if exists)
|
||
4. 8 job cards across the last 7 days (mix of full and wash, some active some done):
|
||
- 3 active job cards (today)
|
||
- 5 done job cards (last 7 days, with final_amount and payment_mode)
|
||
5. Attendance for all 4 staff for the last 14 days (random mix of present/absent/half)
|
||
6. 2 salary payments (one salary, one advance)
|
||
7. 10 parts sales entries spread over last 7 days (various parts, quantities)
|
||
8. 12 cash ledger entries (mix of in/out, various categories)
|
||
Run this with: npm run fullseed (add to package.json)
|
||
|
||
UI POLISH tasks:
|
||
1. Add loading skeleton to all data tables (show 5 gray placeholder rows while fetching)
|
||
2. Add empty state components: when table has no data, show icon + message + action button
|
||
Example: Job Cards empty → "No job cards yet" + "Create First Job Card" button
|
||
3. Add confirmation dialog before "Mark as Done" — "Are you sure? This cannot be undone."
|
||
4. Add toast notifications to ALL create/update actions that don't already have them:
|
||
- Staff add/edit: "Staff added successfully"
|
||
- Attendance save: "Attendance saved for DD/MM/YYYY"
|
||
- Salary payment: "Payment of ₹X recorded for [Staff Name]"
|
||
- Part add: "Part added to inventory"
|
||
- Restock: "Stock updated for [Part Name]"
|
||
- Cash entry: "Cash [In/Out] entry saved"
|
||
5. Fix all currency displays to use ₹ with Indian comma formatting (en-IN locale)
|
||
6. Fix all date displays to use DD/MM/YYYY format
|
||
7. Add active nav item highlight in Sidebar (bold + background for current route)
|
||
8. Make sure forms clear/reset after successful submission
|
||
9. Add "Required field" validation error messages below fields on submit with empty required fields
|
||
10. In Job Cards table, make Reg No uppercase on input
|
||
|
||
FINAL VERIFICATION — Run through all 10 Acceptance Criteria:
|
||
AC-01: Login with admin/swish@2024 → dashboard loads ✓
|
||
AC-02: Create Full job card + Quick Wash job card ✓
|
||
AC-03: Job shows as Active, mark Done with amount+payment ✓
|
||
AC-04: Mark attendance for all staff, save, reload ✓
|
||
AC-05: Log salary payment, view in history ✓
|
||
AC-06: Record parts sale, stock decreases ✓
|
||
AC-07: Cash in and cash out entries ✓
|
||
AC-08: Accounts shows today's income/expense/balance ✓
|
||
AC-09: Download daily report as Excel ✓
|
||
AC-10: All 4 export buttons produce Excel files ✓
|
||
|
||
Report any AC that fails and fix it.
|
||
|
||
Final output should be the complete running app with:
|
||
- Backend on http://localhost:5000
|
||
- Frontend on http://localhost:5173
|
||
- Login: admin / swish@2024
|
||
- All 10 ACs passing
|
||
- Realistic demo data preloaded
|
||
```
|
||
|
||
---
|
||
|
||
## TROUBLESHOOTING PROMPTS
|
||
|
||
Use these if specific things break:
|
||
|
||
### If MySQL connection fails:
|
||
```
|
||
The MySQL connection is failing. Debug this:
|
||
1. Check backend/.env has correct DB_USER, DB_PASS, DB_NAME
|
||
2. Verify MySQL is running: mysql -u root -p
|
||
3. Verify database exists: SHOW DATABASES; (should show swish_gms)
|
||
4. Check backend/src/config/db.js uses mysql2/promise createPool correctly
|
||
5. Test the pool with a simple query: SELECT 1 as test
|
||
Show me the exact error and fix it.
|
||
```
|
||
|
||
### If CORS error in browser:
|
||
```
|
||
There's a CORS error in the browser console. Fix it in backend/src/server.js:
|
||
app.use(cors({
|
||
origin: 'http://localhost:5173',
|
||
credentials: true,
|
||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
|
||
allowedHeaders: ['Content-Type', 'Authorization']
|
||
}));
|
||
Make sure cors() is called BEFORE any route definitions.
|
||
```
|
||
|
||
### If Excel download doesn't work:
|
||
```
|
||
The Excel download is not working. Check:
|
||
1. Frontend axios call uses responseType: 'blob'
|
||
2. Backend sets correct Content-Type header: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||
3. Backend sets Content-Disposition: attachment; filename="..."
|
||
4. XLSX.write uses { type: 'buffer', bookType: 'xlsx' }
|
||
5. res.send(buffer) not res.json(buffer)
|
||
Show me the current code and fix it.
|
||
```
|
||
|
||
### If JWT auth stops working:
|
||
```
|
||
JWT authentication is broken — getting 401 on all protected routes. Debug:
|
||
1. Check frontend axios.ts request interceptor attaches 'Bearer <token>' header
|
||
2. Check localStorage has the key 'gms_token' (open DevTools → Application → Local Storage)
|
||
3. Check backend auth.js extracts token with: authHeader.split(' ')[1]
|
||
4. Check JWT_SECRET in .env matches what was used to sign the token
|
||
5. Log the token on backend: console.log('Token:', token) and verify it's not undefined
|
||
```
|
||
|
||
### If stock deduction race condition:
|
||
```
|
||
Parts stock is going negative. Fix the stock deduction in partsSales route:
|
||
Use atomic UPDATE with stock check:
|
||
const [result] = await db.query(
|
||
'UPDATE parts SET stock_qty = stock_qty - ? WHERE id = ? AND stock_qty >= ?',
|
||
[quantity, part_id, quantity]
|
||
);
|
||
if (result.affectedRows === 0) {
|
||
return res.status(400).json({ error: 'Insufficient stock' });
|
||
}
|
||
// Only insert sale AFTER successful stock deduction
|
||
```
|