Root cause: there was a stale loading overlay outside the tab content
(added by a previous subagent) that rendered when editLoading was true,
covering the entire modal body. Also loadDetailMembership incorrectly
managed editLoading causing state inconsistencies.
Fix:
- Remove the orphaned loading overlay outside tab content blocks
- loadDetailMembership no longer touches editLoading (switchTab owns it)
- switchTab uses Promise.all for parallel loading with formReady guard
- openDetail resets editLoading/formReady to clean state
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- switchTab('edit') now awaits fetchCardTypes and loadDetailMembership
before calling initEditForm, fixing blank form fields for new cards
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix the card types management edit modal that was closing immediately after opening due to event propagation. Added .stop modifier to all action button tap handlers (edit, toggle, delete) to prevent bubbling to parent modal-mask element.
- Changed @tap="openEdit(ct)" to @tap.stop="openEdit(ct)"
- Changed @tap="toggleActive(ct)" to @tap.stop="toggleActive(ct)"
- Changed @tap="confirmDelete(ct)" to @tap.stop="confirmDelete(ct)"
This fixes the bug where the edit modal would open and close in the same event cycle, making it impossible to edit card types.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## Features
### Admin Schedule Page (`packages/app/src/pages/admin/schedule.vue`)
- Interactive date-based slot editor for managing daily schedules
- Real-time slot editing: start/end times, capacity adjustments
- Slot deletion with conflict warnings when bookings exist
- Add new slots with modal dialog
- Live booking status display (booked count, people names)
- Publish/Save changes with sync feedback
- Revert unsaved changes with confirmation
- Skeleton loading states and empty state handling
- Responsive design with optimized mobile UX
### Backend Enhancements
- **New DTO** (`PublishDaySlotsDto`): Structured slot publishing with validation
- Date string validation
- Slot array with existing slot IDs for updates
- Time and capacity validation per slot
- **Schedule Preview API** (`getSchedulePreview`):
- Check for existing published slots
- Fallback to active WeekTemplates for unpublished dates
- Unified response format with isPublished flag
- **Publish Slots API** (`publishDaySlots`):
- Atomic transaction for consistency
- Update existing slots with new times/capacity
- Create new slots from template data
- Delete unpublished slots or set to CLOSED if bookings exist
- Prevent capacity reduction below existing bookings
- Returns all published slots for feedback
### State Management
- Enhanced admin store with schedule state
- Support for pending/unsaved slot changes
- Optimistic UI updates with server sync
### Documentation
- Comprehensive scheduling system architecture docs
- Quick reference for admin workflows
- Flow diagrams and state transitions
- Implementation guide for future maintenance
## Breaking Changes
None
## Testing Recommendations
- Create slots for future dates via schedule editor
- Verify booking prevention for locked/full slots
- Test capacity adjustments with existing bookings
- Confirm template-based schedule generation
- Verify transaction rollback on publish failures
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sub-pages: card purchase with WeChat Pay flow, my memberships with
progress bars, my bookings with tabs, personal info editor
Admin: management center grid, week template CRUD, slot adjustment,
member management with search, order list with filters, card type
CRUD with form modal, studio settings editor
Admin Pinia store for all admin API calls
Home: brand banner, studio info swiper, smart quick entries based on
membership status, upcoming bookings, card shop horizontal scroll
Booking: 7-day date selector, time period filter, slot cards with
status, booking confirm popup with membership picker
Profile: user card with login, training stats, menu with admin entry
8 reusable components: BrandBanner, StudioInfo, QuickEntry,
UpcomingBooking, CardShop, DateSelector, SlotCard, BookingConfirmPopup,
TimePeriodFilter, UserCard, TrainingStats, ProfileMenu
Booking: reservation with atomic transactions, cancellation with refund
logic based on cancelHoursLimit (23 tests)
Payment: WeChat Pay integration (mock), order lifecycle, membership
creation on payment callback (13 tests)
Scheduler: cron tasks for slot generation, cleanup, membership expiry (8 tests)
109 total tests passing across 9 test suites
- pnpm workspace with packages/app, packages/server, packages/shared
- @mp-pilates/shared: enums, constants, TypeScript interfaces for all 8 data models
- @mp-pilates/server: NestJS bootstrap with health check, validation pipe, CORS
- Base TypeScript config with strict mode
Initial design document covering architecture (monorepo with pnpm),
page design, data models, business flows, and API endpoints for
the private Pilates lesson booking WeChat mini-program.