* Localize calendar date pickers to the active UI locale.
Pass the Inertia locale into Reka calendars, translate a11y labels, and use dayjs LL/LLL for DatePicker display text.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Localize remaining dayjs date displays across the UI.
Route list/calendar/preview timestamps through localized LL/LLL helpers so formats follow the active UI locale instead of English or Portuguese-locked patterns.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Use scheduled-or-now timestamps in platform previews.
Drive preview labels from the post schedule when set, localize Discord without dayjs calendar(), and expose a single formatPreviewPostedAt helper.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Fix preview schedule wiring and Discord/Facebook timestamp labels.
Restore hasPickedTime from any saved scheduled_at, keep time on non-today Discord labels, and use a localized just-now fallback for unschedled Facebook previews.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Fix API key expiry day shift and tighten calendar range titles.
Format date-only expiry in UTC calendar days, and use compact dayjs titles for calendar day/week headers.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Replace frontend date source greps with Inertia API key assertions.
Drop the Vue/TS file scanner and assert expiry calendar days through ApiKeyController props instead.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Localize calendar week titles with day-first dayjs formats.
Avoid English month-day order in week headers and chart axis labels so locales like pt-BR keep natural day-first dates.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Split preview timestamp formatting into named platform helpers.
Replace the style-switch formatPreviewPostedAt with clear per-platform helpers so call sites read as formatDiscordPreview / formatXPreview / etc.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
- Create Account model as Cashier Billable entity (stripe, plan, subscription)
- Account owns workspaces and has an owner_id (User)
- User belongs to one Account via account_id
- Workspace belongs to Account via account_id, no longer has billing fields
- Remove Brand model entirely (workspaces serve as grouping)
- Rename brand_limit to workspace_limit in plans
- Workspace roles simplified: admin/member/viewer (owner via Account)
- Invites now belong to Account with workspaces JSON array
- Pennant features scope changed from Workspace to Account
- EnsureSubscribed middleware checks Account subscription
- All controllers updated: BillingController, OnboardingController,
WorkspaceInviteController, SocialController, StripeEventListener
- Frontend: extract GoogleAuthButton component, create WorkspaceRole
enum for type-safe role checks, fix all views for new architecture
- All 1101 tests passing
- Refactor WorkspacePolicy to use pivot role instead of workspace.user_id
- Add manageBilling policy (owner only) to BillingController
- Fix ApiKeyController authorization (view → manageTeam for store/destroy)
- Fix WorkspaceInviteController using workspace.user_id for owner checks
- Fix WorkspaceController settings is_owner using workspace.user_id
- Create PostAction enum for UpdatePost/PostController action strings
- Create ApiToken\Status enum
- Add User::SUBSCRIPTION_NAME constant, replace all hardcoded 'default'
- Convert wantsEmailFor to accept NotificationType enum
- Convert all $data[] to data_get() across publishers, controllers, jobs
- Fix SocialLoginController callback missing try/catch
- Fix SocialController::toggleActive missing workspace null check
- Fix UpdatePost NPE on meta merge when postPlatform not found
- Remove HTML5 required attributes from form inputs
- Convert function declarations to arrow functions in Vue components
- Replace hardcoded URLs with Wayfinder route helpers
- Replace new Date() with dayjs
- Add 16 new test files covering policies, authorization, publishing
- Add API rate limiting (60/min per workspace) in AppServiceProvider
- Add throttle:api middleware to all API routes
- Add rate limit exception rendering for JSON responses
- Add middleware priority list (AuthenticateApiToken before ThrottleRequests)
- Add ApiKeyControllerTest (6 tests for App dashboard CRUD)
- Remove duplicate test files (Controllers/ dir duplicates)
- Remove old controllers and routes/settings.php
- Add routes/mcp.php placeholder
- Add API Keys nav item to settings layout
- Fix LazilyRefreshDatabase conflict in API tests
- 698 tests passing