Add CLAUDE.md project documentation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
89f339a9fd
commit
82293c944d
1 changed files with 220 additions and 0 deletions
220
CLAUDE.md
Normal file
220
CLAUDE.md
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
# Payfrit Business Platform
|
||||
|
||||
Main CFML/JS repository: API + Portal + KDS + HUD + Receipt. Git repo on Forgejo; local clone at `C:\dev\payfrit-biz`.
|
||||
|
||||
## Build & Deploy
|
||||
|
||||
```bash
|
||||
# Edit files directly on dev server via SSH (never locally, never scp)
|
||||
ssh dev.payfrit.com
|
||||
|
||||
# Files live at:
|
||||
# Dev server: /opt/lucee/tomcat/webapps/ROOT/biz.payfrit.com/
|
||||
# Local Lucee: C:\lucee\tomcat\webapps\ROOT\biz.payfrit.com\
|
||||
```
|
||||
|
||||
**Dev symlinks** on dev server: `/api`, `/portal`, `/config` symlink to `biz.payfrit.com/` — edit once, both `dev.payfrit.com` and `biz.payfrit.com` paths work.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
payfrit-biz/
|
||||
├── Application.cfm # Root app config: sessions (30min), datasource, layout wrapper
|
||||
├── index.cfm # Legacy entry point, mode-based routing
|
||||
├── onrequestend.cfm # Footer/cleanup
|
||||
├── register.cfm # Account registration
|
||||
├── confirm_email.cfm # Email verification
|
||||
├── confirm_mobile.cfm # Mobile verification
|
||||
├── reset.cfm # Password reset
|
||||
├── show_order.cfm # Order detail (redirects to /receipt/)
|
||||
├── privacy.html # Privacy policy
|
||||
│
|
||||
├── api/ # REST API (~135 endpoints, 23 domains)
|
||||
│ ├── Application.cfm # Token auth gate (X-User-Token, X-Business-ID headers)
|
||||
│ ├── config/
|
||||
│ │ ├── stripe.cfm # Stripe API keys
|
||||
│ │ └── environment.cfm # Dev vs prod settings
|
||||
│ ├── addresses/ # CRUD delivery addresses (add, delete, list, setDefault, states, types)
|
||||
│ ├── admin/ # Admin utilities
|
||||
│ │ ├── _scripts/ # One-off migration scripts (git-ignored)
|
||||
│ │ ├── quickTasks/ # Task type/category management
|
||||
│ │ └── scheduledTasks/ # Cron coordination
|
||||
│ ├── app/ # App info (about.cfm)
|
||||
│ ├── assignments/ # Employee assignments (delete, list, save)
|
||||
│ ├── auth/ # Authentication (login, loginOTP, sendOTP, verifyOTP, profile, avatar)
|
||||
│ ├── beacons/ # Beacon management (CRUD, lookup, reassign)
|
||||
│ ├── businesses/ # Business profiles (get, list, update, hours, hiring, brandColor)
|
||||
│ ├── chat/ # Order chat (send, get, markRead, close)
|
||||
│ ├── debug/ # Debug endpoints (localhost-protected)
|
||||
│ ├── dev/ # Dev tools (seedData, timeTravel)
|
||||
│ ├── import/ # Menu import (crimson_menu.cfm)
|
||||
│ ├── menu/ # Menu management (items, categories, menus, builder, photos)
|
||||
│ ├── orders/ # Order lifecycle (cart, submit, status, KDS list, history)
|
||||
│ ├── portal/ # Portal-specific (team, stats, settings, searchUser)
|
||||
│ ├── ratings/ # Customer ratings (create, list, submit)
|
||||
│ ├── servicepoints/ # Service point CRUD
|
||||
│ ├── setup/ # Business onboarding wizard (analyze, import, save)
|
||||
│ ├── stations/ # Kitchen stations (list)
|
||||
│ ├── stripe/ # Payments (createPaymentIntent, onboard, status, webhook)
|
||||
│ ├── tasks/ # Task system (accept, complete, create, list, types, categories)
|
||||
│ ├── users/ # User search
|
||||
│ └── workers/ # Worker system (account, onboarding, tier, ledger, earlyUnlock)
|
||||
│
|
||||
├── portal/ # Business management SPA
|
||||
│ ├── index.html # Main dashboard
|
||||
│ ├── login.html # Portal login
|
||||
│ ├── signup.html # Business registration
|
||||
│ ├── menu-builder.html # Interactive menu builder
|
||||
│ ├── setup-wizard.html # Onboarding wizard
|
||||
│ ├── station-assignment.html # Station management
|
||||
│ ├── quick-tasks.html # Quick task interface
|
||||
│ ├── portal.js # Core JS (~169KB, vanilla JS, no framework)
|
||||
│ └── portal.css # Portal styles (~22KB)
|
||||
│
|
||||
├── kds/ # Kitchen Display System
|
||||
│ ├── index.html # Full-screen kitchen display
|
||||
│ ├── admin.html # KDS admin
|
||||
│ ├── debug.html # Debug tools
|
||||
│ └── kds.js # KDS logic (~17KB, 5-second polling)
|
||||
│
|
||||
├── hud/ # Task HUD (Heads Up Display)
|
||||
│ ├── index.html # Full-screen task bars
|
||||
│ └── hud.js # HUD logic (~12KB, 60s target times)
|
||||
│
|
||||
├── receipt/ # Public receipt page (isolated app)
|
||||
│ ├── Application.cfm # Minimal config (no parent layout)
|
||||
│ └── index.cfm # Order receipt by UUID
|
||||
│
|
||||
├── admin/ # Admin tools
|
||||
│ ├── beacons.cfm # Beacon management
|
||||
│ ├── beacon_servicepoint.cfm # Beacon-SP mapping
|
||||
│ ├── email_users.cfm # Bulk email
|
||||
│ ├── god_mode.cfm # Super-admin panel
|
||||
│ └── servicepoints.cfm # Service point management
|
||||
│
|
||||
├── library/cfc/ # ColdFusion components
|
||||
│ ├── businessMaster.cfc # Business data abstraction
|
||||
│ └── twilio.cfc # SMS integration
|
||||
│
|
||||
├── includes/ # Shared includes
|
||||
│ ├── menu.cfm # Menu rendering
|
||||
│ └── track_visitors.cfm # Analytics
|
||||
│
|
||||
├── uploads/ # User-generated content
|
||||
│ ├── categories/ # Category images
|
||||
│ ├── headers/ # Business header images
|
||||
│ ├── items/ # Menu item photos
|
||||
│ ├── logos/ # Business logos
|
||||
│ └── users/ # User profile images
|
||||
│
|
||||
├── cron/
|
||||
│ └── expireStaleChats.cfm # Cleanup old chats
|
||||
│
|
||||
├── css/ # Bootstrap 5.3.0 + custom
|
||||
├── js/ # jQuery 1.11/2.1, Bootstrap JS
|
||||
├── fonts/ # Glyphicons
|
||||
├── images/ # Logo assets
|
||||
├── cfpayment/ # Payment gateway library
|
||||
└── twilio/ # Twilio SMS
|
||||
```
|
||||
|
||||
## Key Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `api/Application.cfm` | Token auth, public endpoint allowlist, perf tracking, datasource config |
|
||||
| `Application.cfm` | Root session management (30min timeout), layout wrapper, business/twilio objects |
|
||||
| `portal/portal.js` | Main portal SPA logic (169KB, vanilla JS, Fetch API) |
|
||||
| `kds/kds.js` | Kitchen display polling & order status management |
|
||||
| `hud/hud.js` | Task visualization with time tracking & beacon alerts |
|
||||
|
||||
## API Authentication
|
||||
|
||||
- **Header**: `X-User-Token` (64-char hex, SHA-256 based)
|
||||
- **Business Context**: `X-Business-ID` header
|
||||
- **Token Table**: `UserTokens` (Token, UserID)
|
||||
- **Public Endpoints**: ~50+ whitelisted in `api/Application.cfm` (no token required)
|
||||
- **OTP Flow**: sendOTP → verifyOTP → token issued
|
||||
- **Magic OTP**: `123456` bypass for App Store review
|
||||
|
||||
## Environment Detection
|
||||
|
||||
```
|
||||
Localhost (127.0.0.1):
|
||||
wwwrootprefix = /biz.payfrit.com/
|
||||
image_display_prefix = http://127.0.0.1:8888/biz.payfrit.com/uploads/
|
||||
uploads_dir = C:\lucee\tomcat\webapps\ROOT\biz.payfrit.com\uploads\
|
||||
|
||||
Production:
|
||||
wwwrootprefix = /
|
||||
image_display_prefix = https://biz.payfrit.com/uploads/
|
||||
uploads_dir = /var/www/biz.payfrit.com/uploads/
|
||||
```
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Backend**: CFML (Lucee), Application.cfm (not .cfc)
|
||||
- **Portal/KDS/HUD**: Vanilla JavaScript (no framework)
|
||||
- **Root pages**: jQuery 1.12.4 (CDN) + Bootstrap 5.3.0 (CDN)
|
||||
- **Payments**: Stripe (webhook at `/api/stripe/webhook.cfm`)
|
||||
- **SMS**: Twilio via `twilio.cfc`
|
||||
- **Database**: `payfrit` datasource
|
||||
|
||||
## Database
|
||||
|
||||
- **Production**: `payfrit` on db.payfrit.com (still uses OLD prefixed column names)
|
||||
- **Development**: `payfrit_dev` on db.payfrit.com (migrated to clean names)
|
||||
|
||||
**Dev DB uses clean, unprefixed names.** PKs are always `ID`. FKs reference their parent table (e.g., `BusinessID`, `UserID`). No table-name prefixes on columns.
|
||||
|
||||
Key tables (dev schema):
|
||||
|
||||
| Table | PK | Key Columns |
|
||||
|-------|----|-------------|
|
||||
| Businesses | `ID` | `Name`, `UserID`, `Phone`, `BrandColor`, `TaxRate`, `OrderTypes`, `StripeAccountID`, `ParentBusinessID` |
|
||||
| Users | `ID` | `FirstName`, `LastName`, `ContactNumber`, `EmailAddress`, `StripeCustomerId`, `UUID` |
|
||||
| Orders | `ID` | `UUID`, `UserID`, `BusinessID`, `StatusID`, `OrderTypeID`, `ServicePointID`, `PaymentStatus` |
|
||||
| Items | `ID` | `BusinessID`, `Name`, `Price`, `CategoryID`, `ParentItemID`, `IsActive`, `SortOrder`, `ImageExtension` |
|
||||
| Categories | `ID` | `BusinessID`, `MenuID`, `ParentCategoryID`, `Name`, `OrderTypes`, `SortOrder` |
|
||||
| OrderLineItems | `ID` | `ParentOrderLineItemID`, `OrderID`, `ItemID`, `StatusID`, `Price`, `Quantity`, `Remark` |
|
||||
| Tasks | `ID` | `BusinessID`, `TaskTypeID`, `Title`, `Details`, `ClaimedByUserID`, `OrderID` |
|
||||
| ServicePoints | `ID` | `BusinessID`, `Name`, `TypeID`, `Code`, `SortOrder`, `IsActive`, `BeaconID` |
|
||||
| Beacons | `ID` | `BusinessID`, `UUID`, `Name`, `IsActive` |
|
||||
| Menus | `ID` | `BusinessID`, `Name`, `IsActive` |
|
||||
|
||||
## Order Status Flow
|
||||
|
||||
1. **Cart** (StatusID 1) → 2. **Submitted** (2) → 3. **Preparing** (3) → 4. **Ready** (4) → 5. **Completed** (5)
|
||||
|
||||
## Receipt Page
|
||||
|
||||
- **URL**: `/receipt/index.cfm?UUID={orderUuid}`
|
||||
- Separate `Application.cfm` — bypasses root layout
|
||||
- Public (no auth) — secured by v4 UUID unguessability
|
||||
- No internal data exposed (no platform fees, commissions, Stripe IDs)
|
||||
|
||||
## Performance Tracking
|
||||
|
||||
API requests track:
|
||||
- `request._perf_start` (getTickCount)
|
||||
- `request._perf_queryCount`
|
||||
- `request._perf_queryTimeMs`
|
||||
|
||||
## Git Configuration
|
||||
|
||||
**Ignored**: `config/claude.json`, `*.tmp`, `*.bak`, `api/admin/_scripts/`
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Add new API endpoint
|
||||
1. Create `.cfm` file in appropriate `api/` subdirectory
|
||||
2. Public endpoints: add to allowlist in `api/Application.cfm`
|
||||
3. Authenticated endpoints work automatically via `X-User-Token`
|
||||
|
||||
### Add new portal page
|
||||
1. Create HTML file in `portal/`
|
||||
2. Add routing/navigation in `portal.js`
|
||||
|
||||
### KDS customization
|
||||
- Refresh interval: `config.refreshInterval` in `kds.js`
|
||||
- Station filtering via URL params
|
||||
Reference in a new issue