Commit Graph

132 Commits

Author SHA1 Message Date
ryan
8aed3e8f88 feat: add cash in/out UI and hide drawer balance from cashier
- Cash In / Cash Out buttons in drawer dialog when open
- Amount + reason form, adjustment history with IN/OUT badges
- Drawer badge shows "Drawer Open" without balance (manager info only)
- API helpers for addAdjustment and getAdjustments

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 20:36:49 +00:00
ryan
c66554f932 feat: add drawer cash in/out adjustments with balance reconciliation
- New drawer_adjustment table (type: cash_in/cash_out, amount, reason)
- POST/GET /drawer/:id/adjustments endpoints
- Drawer close calculation now includes adjustments: expected = opening + sales + cash_in - cash_out
- DrawerAdjustmentSchema for input validation
- 5 new tests (44 total POS tests passing)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 20:24:55 +00:00
ryan
a0be16d848 fix: resolve all frontend lint errors and warnings
All checks were successful
CI / ci (pull_request) Successful in 21s
CI / e2e (pull_request) Successful in 59s
Replace all `any` types with proper types across 36 files:
- TanStack Router search params: `{} as Record<string, unknown>`
- API response pagination: proper typed interface
- DataTable column casts: remove unnecessary `as any`
- Function params and event handlers: use specific types
- Remove unused imports and variables in POS components

Frontend lint now passes with 0 errors and 0 warnings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 20:12:17 +00:00
ryan
1673e18fe8 fix: require open drawer to complete transactions, fix product price field
Some checks failed
CI / ci (pull_request) Failing after 20s
CI / e2e (pull_request) Has been skipped
- Backend enforces open drawer at location before completing any transaction
- Frontend disables payment buttons when drawer is closed with warning message
- Fix product price field name (price, not sellingPrice) in POS API types
- Fix seed UUIDs to use valid UUID v4 format (version nibble must be 1-8)
- Fix Vite allowedHosts for dev.lunarfront.tech access
- Add e2e test for drawer enforcement (39 POS tests now pass)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 19:54:07 +00:00
ryan
bd3a25aa1c feat: add POS register screen with full-screen touch-optimized layout
Standalone register at /pos bypassing the admin sidebar layout:
- Two-panel layout: product search/grid (60%) + cart/payment (40%)
- Product search with barcode scan support (UPC lookup on Enter)
- Custom item entry dialog for ad-hoc items
- Cart with line items, tax, totals, and remove-item support
- Payment dialogs: cash (quick amounts + change calc), card, check
- Drawer open/close with balance reconciliation and over/short
- Auto-creates pending transaction on first item added
- POS link added to admin sidebar nav (module-gated)
- Zustand store for POS session state, React Query for server data

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 19:29:37 +00:00
ryan
aa5b53920d feat: add app configuration UI to settings page
All checks were successful
CI / ci (pull_request) Successful in 17s
CI / e2e (pull_request) Successful in 47s
Log level dropdown on the settings page lets admins change the application
log verbosity at runtime without restarting. Uses the new /v1/config API
with the existing settings.view/settings.edit permissions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 19:04:31 +00:00
ryan
772d5578ad feat: add app_config table with runtime log level control and POS structured logging
All checks were successful
CI / ci (pull_request) Successful in 20s
CI / e2e (pull_request) Successful in 56s
- New app_config key-value table for system settings, with in-memory cache (mirrors ModuleService pattern)
- GET/PATCH /v1/config endpoints for reading and updating config (settings.view/settings.edit permissions)
- Runtime log level: PATCH /v1/config/log_level applies immediately, persists across restarts
- Startup loads log level from DB in onReady hook (env var is default, DB overrides)
- Add structured request.log.info() to POS routes: transaction create/complete/void, drawer open/close, discount create/update/delete

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 18:56:21 +00:00
ryan
8256380cd1 feat: add cash rounding, POS test suite, and fix test harness port cleanup
All checks were successful
CI / ci (pull_request) Successful in 20s
CI / e2e (pull_request) Successful in 50s
- Add Swedish rounding (nearest nickel) for cash payments at locations with cash_rounding enabled
- Add rounding_adjustment column to transactions, cash_rounding to locations
- Add POS schema to database plugin for relational query support
- Complete/void routes now return full transaction with line items via getById
- Test harness killPort falls back to fuser when lsof unavailable (fixes stale process bug)
- Add 35-test POS API suite covering discounts, drawer, transactions, tax, rounding, e2e flow
- Add unit tests for tax service and POS Zod schemas

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 18:23:05 +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
lunarfront-bot
2231f06234 chore: bump version to v0.1.1
All checks were successful
Build & Release / build (push) Has been skipped
2026-04-04 02:31:04 +00:00
lunarfront-bot
36eb377583 chore: bump version to v0.1.0
All checks were successful
Build & Release / build (push) Has been skipped
2026-04-04 01:08:32 +00:00
lunarfront-bot
0034e0b8b3 chore: bump version to v0.0.29
All checks were successful
Build & Release / build (push) Has been skipped
2026-04-04 00:49:46 +00:00
Ryan Moon
358e07b1d5 feat: remove per-customer valkey, use managed Valkey with REDIS_KEY_PREFIX 2026-04-03 19:48:48 -05:00
lunarfront-bot
5df914a40f chore: bump version to v0.0.28
All checks were successful
Build & Release / build (push) Has been skipped
2026-04-04 00:47:43 +00:00
lunarfront-bot
ff2e4586f3 chore: bump version to v0.0.27
All checks were successful
Build & Release / build (push) Has been skipped
2026-04-04 00:36:04 +00:00
lunarfront-bot
0e3a8d7504 chore: bump version to v0.0.26
All checks were successful
Build & Release / build (push) Has been skipped
2026-04-03 01:36:38 +00:00
lunarfront-bot
384f985a77 chore: bump version to v0.0.25
Some checks failed
Build & Release / build (push) Has been skipped
CI / ci (push) Successful in 1m37s
CI / e2e (push) Failing after 5s
2026-04-02 02:45:21 +00:00
ryan
5b56a2c219 Merge pull request 'feat/ci-cd-pipeline' (#5) from feat/ci-cd-pipeline into main
Reviewed-on: #5
2026-04-02 02:45:05 +00:00
Ryan Moon
c01d19215d fix: skip test failure when no test files exist in backend 2026-04-01 21:08:01 -05:00
Ryan Moon
744256ae9f fix: pass with no tests in backend until unit tests are added 2026-04-01 21:06:15 -05:00
Ryan Moon
05f926c0dc fix: remove unused imports and dead code to clear ESLint errors 2026-04-01 20:34:56 -05:00
Ryan Moon
0f8aff9426 fix: resolve ESLint errors — remove unused imports and dead code 2026-04-01 20:18:13 -05:00
lunarfront-bot
97638b888e chore: bump version to v0.0.24 2026-04-02 01:07:20 +00:00
lunarfront-bot
a561b184e1 chore: bump version to v0.0.23 2026-04-02 01:06:36 +00:00
lunarfront-bot
7864c07be1 chore: bump version to v0.0.22 2026-04-02 01:06:10 +00:00
lunarfront-bot
1e38d69b21 chore: bump version to v0.0.21 2026-04-02 01:05:45 +00:00
lunarfront-bot
eb9e669233 chore: bump version to v0.0.20 2026-04-02 01:05:20 +00:00
lunarfront-bot
13db5ce5f1 chore: bump version to v0.0.19 2026-04-02 01:04:52 +00:00
lunarfront-bot
babfccaa1b chore: bump version to v0.0.18 2026-04-02 01:04:24 +00:00
lunarfront-bot
1aa29dfb31 chore: bump version to v0.0.17 2026-04-02 01:04:02 +00:00
lunarfront-bot
efb55bc784 chore: bump version to v0.0.16 2026-04-02 01:03:40 +00:00
lunarfront-bot
9cdb2cf427 chore: bump version to v0.0.15 2026-04-02 01:03:19 +00:00
lunarfront-bot
135b88029a chore: bump version to v0.0.14 2026-04-02 01:02:59 +00:00
lunarfront-bot
23df7feaf1 chore: bump version to v0.0.13 2026-04-02 01:02:38 +00:00
lunarfront-bot
2e2832b1e3 chore: bump version to v0.0.12 2026-04-02 01:02:24 +00:00
lunarfront-bot
dd846bc86a chore: bump version to v0.0.11 2026-04-02 01:02:11 +00:00
lunarfront-bot
25e9177554 chore: bump version to v0.0.10 2026-04-02 01:01:51 +00:00
lunarfront-bot
cfd1561de9 chore: bump version to v0.0.9 2026-04-02 01:01:29 +00:00
lunarfront-bot
6304d14e56 chore: bump version to v0.0.8 2026-04-02 01:01:07 +00:00
lunarfront-bot
e4fe42c6ec chore: bump version to v0.0.7 2026-04-02 01:00:42 +00:00
lunarfront-bot
27a9900787 chore: bump version to v0.0.6 2026-04-02 01:00:15 +00:00
lunarfront-bot
90cbff0611 chore: bump version to v0.0.5 2026-04-02 00:59:46 +00:00
lunarfront-bot
ddae05dc3f chore: bump version to v0.0.4 2026-04-02 00:59:22 +00:00
lunarfront-bot
12fa36a7b0 chore: bump version to v0.0.3 2026-04-02 00:59:00 +00:00
lunarfront-bot
fc7d92e33f chore: bump version to v0.0.2 2026-04-02 00:58:35 +00:00
Ryan Moon
c2b1073fef feat: add CI/CD pipeline, production Dockerfile, and deployment architecture
- Add production Dockerfile with bun build --compile, multi-stage Alpine build
- Add .dockerignore
- Swap bcrypt -> bcryptjs (pure JS, no native addons)
- Add programmatic migrations on startup via drizzle migrator
- Add /v1/version endpoint with APP_VERSION baked in at build time
- Add .gitea/workflows/ci.yml (lint + test with postgres/valkey services)
- Add .gitea/workflows/build.yml (version bump, build, push to registry)
- Update CLAUDE.md and docs/architecture.md to remove multi-tenancy
- Add docs/deployment.md covering DOKS + ArgoCD architecture

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 19:50:37 -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
5ad27bc196 Add lessons module, rate cycles, EC2 deploy scripts, and help content
- Lessons module: lesson types, instructors, schedule slots, enrollments,
  sessions (list + week grid view), lesson plans, grading scales, templates
- Rate cycles: replace monthly_rate with billing_interval + billing_unit on
  enrollments; add weekly/monthly/quarterly rate presets to lesson types and
  schedule slots with auto-fill on enrollment form
- Member detail page: tabbed layout for details, identity documents, enrollments
- Sessions week view: custom 7-column grid replacing react-big-calendar
- Music store seed: instructors, lesson types, slots, enrollments, sessions,
  grading scale, lesson plan template
- Scrollbar styling: themed to match sidebar/app palette
- deploy/: EC2 setup and redeploy scripts, nginx config, systemd service
- Help: add Lessons category (overview, types, instructors, slots, enrollments,
  sessions, plans/grading); collapsible sidebar with independent scroll;
  remove POS/accounting references from docs
2026-03-30 18:52:57 -05:00
Ryan Moon
7680a73d88 Add Phase 8: lesson plan templates with deep-copy instantiation
- New tables: lesson_plan_template, lesson_plan_template_section, lesson_plan_template_item
- skill_level enum: beginner, intermediate, advanced, all_levels
- Templates are reusable curriculum definitions independent of any member/enrollment
- POST /lesson-plan-templates/:id/create-plan deep-copies the template into a member plan
- Instantiation uses template name as default plan title, accepts custom title override
- Instantiation deactivates any existing active plan on the enrollment (one-active rule)
- Plan items are independent copies — renaming the template does not affect existing plans
- 11 new integration tests
2026-03-30 10:37:30 -05:00