ryan
95cf017b4b
feat: repair-POS integration, receipt formats, manager overrides, price adjustments
...
- Add thermal/full-page receipt format toggle (per-device, localStorage)
- Full-page receipt uses clean invoice layout matching repair PDF style
- Settings page reorganized into tabbed sections (Store, Locations, Modules, Receipt, POS Security, Advanced)
- Manager override system: configurable PIN prompt for void, refund, discount, cash in/out
- Discount threshold setting: require manager approval above X%
- Consumable product type: tracked for internal job costing, excluded from POS search, receipts, and customer-facing totals
- Repair line item dialog: product picker dropdown for parts/consumables from inventory
- Repair → POS checkout: load ready-for-pickup tickets into repair_payment transactions with proper tax categories (labor=service, parts=goods)
- Transaction completion auto-updates repair ticket status to picked_up
- POS Repairs dialog with Pickup and New Intake tabs, customer account lookup
- Inline price adjustment on cart items: % off, $ off, or set price with live preview
- Order-level discount button with same three input modes
- Backend: migration 0043 (consumable enum + is_consumable flag), createFromRepairTicket service, ready-for-pickup endpoint
- Fix: backend dev script uses --env-file for turbo compatibility
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-05 16:05:19 +00:00
ryan
7b15f18e59
feat: add core POS module — transactions, discounts, drawer, tax
...
Phase 3a backend API for point-of-sale. Includes:
Schema (packages/backend/src/db/schema/pos.ts):
- pgEnums: transaction_type, transaction_status, payment_method,
discount_type, discount_applies_to, drawer_status
- Tables: transaction, transaction_line_item, discount,
discount_audit, drawer_session
- Transaction links to accounts, repair_tickets, repair_batches
- Line items link to products and inventory_units
Tax system:
- tax_rate + service_tax_rate columns on location
- tax_category enum (goods/service/exempt) on product
- Tax resolves per line item: goods→tax_rate, service→service_tax_rate,
exempt→0. Repair line items map: part→goods, labor→service
- GET /tax/lookup/:zip stubbed for future API integration (TAX_API_KEY)
Services (export const pattern, matching existing codebase):
- TransactionService: create, addLineItem, removeLineItem, applyDiscount,
recalculateTotals, complete (decrements inventory), void, getReceipt
- DiscountService: CRUD + listAll for dropdowns
- DrawerService: open/close with expected balance + over/short calc
- TaxService: getRateForLocation (by tax category), calculateTax
Routes:
- POST/GET /transactions, GET /transactions/:id, GET /transactions/:id/receipt
- POST /transactions/:id/line-items, DELETE /transactions/:id/line-items/:id
- POST /transactions/:id/discounts, /complete, /void
- POST /drawer/open, POST /drawer/:id/close, GET /drawer/current, GET /drawer
- CRUD /discounts + GET /discounts/all
- GET /products/lookup/upc/:upc (barcode scanner support)
All routes gated by pos.view/pos.edit/pos.admin + withModule('pos').
POS module already seeded in migration 0026.
Still needed: bun install, drizzle-kit generate + migrate, tests, lint.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-04 16:26:38 +00:00
Ryan Moon
0f8aff9426
fix: resolve ESLint errors — remove unused imports and dead code
2026-04-01 20:18:13 -05:00
Ryan Moon
bde3ad64fd
Fix code review items: atomic qty increment, unit updatedAt, suppliers/all endpoint, SKU unique index
2026-03-31 05:08:01 -05:00
Ryan Moon
5f5ba9e4a2
Build inventory frontend and stock management features
...
- Full inventory UI: product list with search/filter, product detail with
tabs (details, units, suppliers, stock receipts, price history)
- Product filters: category, type (serialized/rental/repair), low stock,
active/inactive — all server-side with URL-synced state
- Product-supplier junction: link products to multiple suppliers with
preferred flag, joined supplier details in UI
- Stock receipts: record incoming stock with supplier, qty, cost per unit,
invoice number; auto-increments qty_on_hand for non-serialized products
- Price history tab on product detail page
- categories/all endpoint to avoid pagination limit on dropdown fetches
- categoryId filter on product list endpoint
- Repair parts and additional inventory items in music store seed data
- isDualUseRepair corrected: instruments set to false, strings/parts true
- Product-supplier links and stock receipts in seed data
- Price history seed data simulating cost increases over past year
- 37 API tests covering categories, suppliers, products, units,
product-suppliers, and stock receipts
- alert-dialog and checkbox UI components
- sync-and-deploy.sh script for rsync + remote deploy
2026-03-30 20:12:07 -05:00
Ryan Moon
9400828f62
Rename Forte to LunarFront, generalize for any small business
...
Rebrand from Forte (music-store-specific) to LunarFront (any small business):
- Package namespace @forte/* → @lunarfront/*
- Database forte/forte_test → lunarfront/lunarfront_test
- Docker containers, volumes, connection strings
- UI branding, localStorage keys, test emails
- All documentation and planning docs
Generalize music-specific terminology:
- instrumentDescription → itemDescription
- instrumentCount → itemCount
- instrumentType → itemCategory (on service templates)
- New migration 0027_generalize_terminology for column renames
- Seed data updated with generic examples
- RBAC descriptions updated
2026-03-30 08:51:54 -05:00
Ryan Moon
d36c6f7135
Remove multi-tenant company_id scoping from entire codebase
...
Drop company_id column from all 22 domain tables via migration.
Remove companyId from JWT payload, auth plugins, all service method
signatures (~215 occurrences), all route handlers (~105 occurrences),
test runner, test suites, and frontend auth store/types.
The company table stays as store settings (name, timezone). Tenant
isolation in a SaaS deployment would be at the database level (one
DB per customer) not the application level.
All 107 API tests pass. Zero TSC errors across all packages.
2026-03-29 14:58:33 -05:00
Ryan Moon
b9f78639e2
Add paginated users/roles, user status, frontend permissions, profile pictures, identifier file storage
...
- Users page: paginated, searchable, sortable with inline roles (no N+1)
- Roles page: paginated, searchable, sortable + /roles/all for dropdowns
- User is_active field with migration, PATCH toggle, auth check (disabled=401)
- Frontend permission checks: auth store loads permissions, sidebar/buttons conditional
- Profile pictures via file storage for users and members, avatar component
- Identifier images use file storage API instead of base64
- Fix TypeScript errors across admin UI
- 64 API tests passing (10 new)
2026-03-29 08:16:34 -05:00
Ryan Moon
e65175ef19
Fix security issues: path traversal, typed errors, file validation
...
- Fix path traversal in file serve endpoint (validate company prefix, block ..)
- Add typed error classes: ValidationError, NotFoundError, ForbiddenError,
ConflictError, StorageError
- Global error handler catches AppError subclasses with correct status codes
- 4xx logged as warn, 5xx as error with request ID
- File upload validates entityType whitelist, UUID format, category pattern
- Remove fragile string-matching error handling from routes
- Services throw typed errors instead of plain Error
- Health endpoint documented as intentionally public
2026-03-28 16:03:45 -05:00
Ryan Moon
0a2d6e23af
Add lookup tables, payment methods, tax exemptions, and processor link APIs
...
Replace unit_status and item_condition pgEnums with company-scoped lookup
tables that support custom values. Add account_payment_method table,
tax_exemption table with approve/revoke workflow, and CRUD routes for
processor links. Validate inventory unit status/condition against lookup
tables at service layer.
2026-03-27 20:53:30 -05:00
Ryan Moon
750dcf4046
Refactor all list APIs for server-side pagination, search, and sort
...
All list endpoints now return paginated responses:
{ data: [...], pagination: { page, limit, total, totalPages } }
Query params: ?page=1&limit=25&q=search&sort=name&order=asc
Changes:
- Added PaginationSchema in @forte/shared for consistent param parsing
- Added pagination utils (withPagination, withSort, buildSearchCondition,
paginatedResponse) in backend
- Refactored all services: AccountService, MemberService, CategoryService,
SupplierService, ProductService, InventoryUnitService
- Merged separate /search endpoints into list endpoints via ?q= param
- Removed AccountSearchSchema and ProductSearchSchema (replaced by
PaginationSchema)
- Added pagination test (5 items, page 1 limit 2, expect totalPages=3)
- Updated CLAUDE.md with API conventions
- 34 tests passing
2026-03-27 19:53:59 -05:00
Ryan Moon
1132e0999b
Add products, inventory units, stock receipts, and price history
...
- product table (catalog definition, no cost column — cost tracked
per receipt/unit)
- inventory_unit table (serialized items with serial number,
condition, status)
- stock_receipt table (FIFO cost tracking — records every stock
receive event with cost_per_unit, supplier, date)
- price_history table (logs every retail price change for margin
analysis over time)
- product_supplier join table (many-to-many, tracks supplier SKU
and preferred supplier)
- Full CRUD routes + search (name, SKU, UPC, brand)
- Inventory unit routes nested under products
- Price changes auto-logged on product update
- 33 tests passing
2026-03-27 18:22:39 -05:00