Commit Graph

34 Commits

Author SHA1 Message Date
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
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
a51f1f5141 Add vault category permissions dialog with role/user management 2026-03-30 07:23:23 -05:00
Ryan Moon
4438188362 Fix vault dialog autofill: prevent browser password manager from overriding dark theme colors 2026-03-30 07:18:58 -05:00
Ryan Moon
e346e072b8 Add module management system for enabling/disabling features
Stores can enable/disable feature modules from Settings. When disabled,
nav links are hidden and API routes return 403. Designed as the
foundation for future license-based gating (licensed + enabled flags).

Core modules (Accounts, Members, Users, Roles, Settings) are always on.

- module_config table with slug, name, description, licensed, enabled
- In-memory cache for fast per-request module checks
- requireModule middleware wraps route groups in main.ts
- Settings page Modules card with toggle switches
- Sidebar hides nav links for disabled modules
- Default modules seeded: inventory, pos, repairs, rentals, lessons,
  files, vault, email, reports
2026-03-30 06:52:27 -05:00
Ryan Moon
1f9297f533 Add vault secret manager frontend UI
Three-state page: not initialized → locked → unlocked.
Any user with vault.view can unlock (for store opening).
Admins can lock and change master password.

- Two-panel layout: categories on left, entries on right
- Entry reveal button shows decrypted value for 30s with copy
- Add/edit/delete entries and categories
- KeyRound icon in sidebar navigation
2026-03-30 06:17:58 -05:00
Ryan Moon
51ca2ca683 Add folder permissions UI and WebDAV protocol support
Permissions UI:
- FolderPermissionsDialog component with public/private toggle,
  role/user permission management, and access level badges
- Integrated into file manager toolbar (visible for folder admins)
- Backend returns accessLevel in folder detail endpoint

WebDAV server:
- Full WebDAV protocol at /webdav/ with Basic Auth (existing credentials)
- PROPFIND, GET, PUT, DELETE, MKCOL, COPY, MOVE, LOCK/UNLOCK support
- Permission-checked against existing folder access model
- In-memory lock stubs for Windows client compatibility
- 22 API integration tests covering all operations

Also fixes canAccess to check folder creator (was missing).
2026-03-29 17:38:57 -05:00
Ryan Moon
cbbf2713a1 Enlarge logo upload area to 256x128 for better preview 2026-03-29 16:39:36 -05:00
Ryan Moon
f9bf1c9bff Add rectangular logo upload to settings, support SVG content type
Settings page now shows a rectangular upload area for the store logo
instead of circular avatar. Uses authenticated image fetching with
blob URL cleanup. Accepts SVG in addition to JPEG/PNG/WebP. SVG
added to file serve content type map. Simplified to single logo
image (used on PDFs, sidebar, and login).
2026-03-29 16:27:02 -05:00
Ryan Moon
8d75586f8b Add store logo and app icon uploads to settings page
AvatarUpload component now supports custom category and placeholder
icon props. Settings page shows two upload circles: Store Logo (for
PDFs/invoices, uses ImageIcon placeholder) and App Icon (for sidebar/
login, uses Building placeholder). Added 'company' to allowed file
entity types.
2026-03-29 16:14:08 -05:00
Ryan Moon
653fff6ce2 Add store settings page with location management
Company table gains address and logo_file_id columns. New store
settings API: GET/PATCH /store for company info, full CRUD for
/locations. Settings page shows store name, phone, email, address,
timezone with inline edit. Location cards with add/edit/delete.
Settings link in admin sidebar. Fixes leftover company_id on
location table and seed files.
2026-03-29 15:56:02 -05:00
Ryan Moon
0f6cc104d2 Add shared file storage with folder tree, permissions, and file manager UI
New document hub for centralized file storage — replaces scattered
drives and USB sticks for non-technical SMBs. Three new tables:
storage_folder (nested hierarchy), storage_folder_permission (role
and user-level access control), storage_file.

Backend: folder CRUD with nested paths, file upload/download via
signed URLs, permission checks (view/edit/admin with inheritance
from parent folders), public/private toggle, breadcrumb navigation,
file search.

Frontend: two-panel file manager — collapsible folder tree on left,
icon grid view on right. Folder icons by type, file size display,
upload button, context menu for download/delete. Breadcrumb nav.
Files sidebar link added.
2026-03-29 15:31:20 -05:00
Ryan Moon
55f8591cf1 Add dev seed data, batch status progress bar, pre-fill account from batch
Dev seed script creates 8 accounts, 8 members, 16 repair templates,
6 repair tickets in various statuses, and a school batch with 5
instruments. Run with bun run db:seed-dev.

Batch detail page now has a status progress bar matching the ticket
detail pattern. Add Repair from batch pre-fills the account and
contact name. New repair form reads accountId and contactName from
search params when linked from a batch.
2026-03-29 14:04:02 -05:00
Ryan Moon
f7e78bec84 Improve repair batches: account search, add repair button, batch PDF
Batch create form now uses searchable account picker (same as ticket
intake) instead of a dropdown. Batch detail shows + Add Repair button
that creates a ticket pre-linked to the batch. Repair count and total
estimate auto-calculated from linked tickets. Batch PDF generates a
summary with all repairs, statuses, estimates, and grand total. Added
Mark Delivered button for completed batches. New repair form shows
batch badge when linked from a batch.
2026-03-29 13:38:25 -05:00
Ryan Moon
916eb29895 Add PDF generation modal with content picker, repairs help pages
PDF button now opens a modal where staff can select which line items,
customer-visible notes, and photos to include before generating. Defaults
to all customer notes and completed photos. Replaces the old one-click
generation.

Added 4 help/wiki pages for the Repairs module: Repairs Overview, Repair
Templates, Repair Batches, and Notes & Photos. Covers ticket workflow,
template usage, batch management, note visibility, photo phases, and
signed approval process. Updated Getting Started nav to include Repairs.
2026-03-29 13:20:32 -05:00
Ryan Moon
b0379052d6 Add 'new' status as default, in_transit becomes branch state
New tickets start as 'new' (just created, not yet examined). In Transit
is now a branch status off New for school pickups and shipped instruments.
Intake means the instrument has been physically received and documented.
Status progress bar, labels, filters, and default status all updated.
Removed debug logging from file upload endpoint.
2026-03-29 11:45:41 -05:00
Ryan Moon
ee8d6f7aad Add jsPDF dependency and PDF generation module for repair tickets
Install jsPDF, add generate-pdf.ts with customer-facing PDF layout,
wire PDF button in ticket detail to generate and auto-upload.
2026-03-29 10:52:17 -05:00
Ryan Moon
79b7377fd2 Restructure ticket detail into tabs, add documents section
Ticket detail page now uses tabs (Details, Line Items, Notes, Photos &
Docs) instead of a long scrolling page. Photos section gains a Documents
category for uploading signed approvals, quotes, and receipts (accepts
PDFs). PDF generation button added to header (stub for now).
2026-03-29 10:42:40 -05:00
Ryan Moon
7eac03f6c2 Add repair notes journal with running feed, visibility, and status tagging
New repair_note table for timestamped journal entries on tickets. Each
note captures author, content, visibility (internal or customer-facing),
and the ticket status at time of writing. Notes display as a running
feed on the ticket detail page with newest first. Internal notes have
a lock icon, customer-visible notes highlighted in blue. Supports add
and delete with appropriate permission gating.
2026-03-29 10:27:39 -05:00
Ryan Moon
01cff80f2b Add repair list filters, template management page, and backend filter support
Repairs list now has a filter panel with status (defaults to active only),
condition, batch/individual toggle, and date range filters for intake and
promised dates. Added Batch column to the repairs table. Backend list
endpoint accepts filter query params for status, condition, dates, and
batch membership. Template management page (admin only) with CRUD for
common repair services (rehair, string change, etc.) with instrument
type, size, and default pricing. Sidebar updated with Repair Templates
link gated on repairs.admin permission.
2026-03-29 10:13:38 -05:00
Ryan Moon
7d55fbe7ef Add repair ticket detail improvements and intake estimate builder
Status progress bar component with visual step indicator, in_transit
status for instruments being transported to shop. Ticket detail page
reworked with inline edit form, reopen for cancelled tickets, photos
grouped by repair phase (intake/in_progress/completed). Intake form
now supports building estimates with template picker and manual line
items that carry over to the ticket. Service template API client and
types added for template search in line item dialogs.
2026-03-29 09:56:28 -05:00
Ryan Moon
f17bbff02c Add repairs domain with tickets, line items, batches, and service templates
Full-stack implementation of instrument repair tracking: DB schema with
repair_ticket, repair_line_item, repair_batch, and repair_service_template
tables. Backend services and routes with pagination/search/sort. 20 API
tests covering CRUD, status workflow, line items, and batch operations.
Admin frontend with ticket list, detail with status progression, line item
management, batch list/detail with approval workflow, and new ticket form
with searchable account picker and intake photo uploads.
2026-03-29 09:12:40 -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
7dea20e818 Add user profile page, password change, reset links, auto-seed RBAC
Backend:
- POST /v1/auth/change-password (current user)
- POST /v1/auth/reset-password/:userId (admin generates 24h signed link)
- POST /v1/auth/reset-password (token-based reset, no auth required)
- GET/PATCH /v1/auth/me (profile read/update)
- Auto-seed system permissions on server startup

Frontend:
- Profile page with name edit, password change, theme/color settings
- Sidebar user link goes to profile page (replaces dropdown)
- Users page: "Reset Password Link" in kebab (copies to clipboard)
- Sign out button below profile link
2026-03-28 17:59:55 -05:00
Ryan Moon
58bf54a251 Add roles and users admin UI with role management API
Backend:
- GET /v1/users (list company users)
- GET/POST/PATCH/DELETE /v1/roles (role CRUD with permissions)
- GET/POST/DELETE /v1/users/:userId/roles (role assignment)
- GET /v1/me/permissions (current user's effective permissions)

Frontend:
- Roles list page with kebab menu (edit permissions, delete custom)
- Role detail page with grouped permission checkboxes and inheritance note
- New role page with auto-generated slug
- Users list page showing assigned roles per user
- Manage Roles dialog for adding/removing roles per user
- Sidebar: Admin section with Users, Roles, Help links
2026-03-28 17:16:53 -05:00
Ryan Moon
f359f92071 Fix members routing - restructure as directory for detail page to work
Move members.tsx to members/index.tsx so $memberId.tsx resolves as a
sibling route. Fixes member detail page not loading when navigating
from members list.
2026-03-28 13:30:30 -05:00
Ryan Moon
95bf9472e0 Add member identifiers UI, member detail page, kebab menus
- Member detail page at /members/:id with edit form and identity documents
- Expandable identity documents on account members tab
- Kebab menu on both members list and account members tab (Edit, View IDs, View Account, Delete)
- Identifier form with image upload (base64), ID type select, dates
- Wiki article for identity documents
2026-03-28 13:22:44 -05:00
Ryan Moon
c7e2c141ec Add in-app wiki help system with accounts and members articles
Markdown-based help pages rendered in the admin UI. Sidebar category
navigation with search. Articles: Getting Started, Accounts Overview,
Members Overview, Payment Methods, Tax Exemptions. Written for
non-technical store staff.
2026-03-28 13:05:52 -05:00
Ryan Moon
b9e984cfa3 Add member address, state normalization, account inheritance, fix member form
- Address field on member table (jsonb, same format as account)
- Members inherit email, phone, address from account when not provided
- State normalization: "Texas" → "TX", "california" → "CA" via shared util
- Member form drops zodResolver to fix optional field validation flashing
- Account name auto-format: "First Last - Account"
- US state lookup with full name + code support
2026-03-28 12:31:02 -05:00
Ryan Moon
6ca38e2105 Fix account/member form validation, add member number to tables
- Fix account create form blocking on empty name when includeFirstMember
- Add noValidate to forms to prevent browser native validation on optional fields
- Show member number column on account members tab
- Replace DOB with phone in members table for better at-a-glance info
2026-03-28 11:31:28 -05:00
Ryan Moon
8ea3b8dffb Add auto-generated account numbers and member numbers
6-digit random numbers generated on create, unique per company. Member
number column added to member table. Both displayed in UI tables.
2026-03-28 09:15:27 -05:00
Ryan Moon
572af05a3f Add top-level members list, primary member on account, member move, combined create flows
- GET /v1/members with search across all members (includes account name)
- POST /members/:id/move with optional accountId (creates new account if omitted)
- primary_member_id on account table, auto-set when first member added
- isMinor flag on member create (manual override when no DOB provided)
- Account search now includes member names
- New account form includes primary contact fields, auto-generates name
- Members page in sidebar with global search
2026-03-28 09:08:06 -05:00
Ryan Moon
9abdf6c050 Add accounts UI with list, create, edit, detail tabs for all sub-entities
Accounts list with paginated table, search, sort. Account detail page with
tabs for members, payment methods, tax exemptions, and processor links.
All sub-entities have create/edit dialogs and delete actions. Forms use
shared Zod schemas via react-hook-form.
2026-03-28 07:45:52 -05:00
Ryan Moon
e734ef4606 Scaffold @forte/admin package with React, Vite, shadcn/ui, TanStack Router
Sets up the admin frontend with login page, auth guard, API client, Zustand
auth store, and all shadcn/ui components. Vite proxies /v1 to backend in dev.
2026-03-28 07:35:12 -05:00