Commit graph

177 commits

Author SHA1 Message Date
Paulo Castellano
8e33f9ce4f feat: add error_context column to post_platforms for structured error debugging 2026-04-01 11:07:21 -03:00
Paulo Castellano
5903f0d894 docs: add publishing hardening spec (6 improvements from Postiz comparison) 2026-04-01 10:59:08 -03:00
Paulo Castellano
c48c774e23 feat: publishing engine improvements — rate limit retry, inline token refresh, per-platform queues, proactive refresh
- Add HasSocialHttpClient trait with 429 rate limit retry (3 attempts, 5s delay)
- Integrate trait into all 10 publishers (YouTube uses Google SDK)
- Add inline token refresh retry in PublishToSocialPlatform job
- Add per-platform Horizon queues via Platform::queue() and Platform::allQueues()
- Add RefreshExpiringTokens hourly command for proactive token refresh
- Fix token leaks: redact response bodies in all Log::error calls
- Fix token leaks: remove $response->body() from exception messages
- Fix ConnectionVerifier: redact all refresh error logs
- Fix null checks on API response IDs (Instagram, Threads, Pinterest, Facebook)
- Fix PublishPost::failed() to mark post as failed
- Fix StoreChunkedMediaRequest: validate max 1GB total size
- Fix scheduled_at validation: string → date
- Fix StoreMediaRequest: images max 10MB, videos max 1GB, only MP4 video
2026-04-01 10:51:53 -03:00
Paulo Castellano
6a26707dc8 docs: add publishing engine improvements plan (tasks 1-4 now, 5-6 future) 2026-04-01 09:49:09 -03:00
Paulo Castellano
33cbc57b59 docs: add publishing engine improvements spec (Postiz comparison) 2026-04-01 09:43:15 -03:00
Paulo Castellano
cebaaaf60b test: add comprehensive publisher tests for all media flows and edge cases 2026-04-01 09:32:43 -03:00
Paulo Castellano
ce46a4d984 fix: close Facebook streams, check download responses, X stream upload 2026-04-01 08:59:47 -03:00
Paulo Castellano
45dd3f4bde fix: file handle leaks, return types, Facebook reel/story binary upload, null checks, cleanup 2026-03-31 22:41:26 -03:00
Paulo Castellano
e90a24fc31 fix: Pinterest video try/finally, LinkedIn/Mastodon stream uploads, close file handles 2026-03-31 22:18:05 -03:00
Paulo Castellano
307b496bad fix: separate image/video upload limits (10MB/1GB), accept only MP4 video 2026-03-31 22:13:04 -03:00
Paulo Castellano
0cf84e4424 chore: remove verbose Log::info, add GD memory check, redact tokens in exception context 2026-03-31 22:04:12 -03:00
Paulo Castellano
6e3dac7a66 fix: GD memory safety check and redact tokens from exception context 2026-03-31 22:01:59 -03:00
Paulo Castellano
2883793441 chore: remove verbose Log::info from all publishers 2026-03-31 22:01:14 -03:00
Paulo Castellano
aa6bc88335 fix: code review issues — Instagram arg count, LinkedIn file handle, TikTok data_get, YouTube token timestamp 2026-03-31 21:46:58 -03:00
Paulo Castellano
6c2a354594 refactor: remove unused context param from handleApiError across all publishers 2026-03-31 21:43:30 -03:00
Paulo Castellano
30bfb2a890 refactor: use data_get in MediaOptimizer for consistency 2026-03-31 21:25:37 -03:00
Paulo Castellano
4ddb4d941a feat: integrate MediaOptimizer into all image-uploading publishers 2026-03-31 21:22:57 -03:00
Paulo Castellano
02298f31a6 refactor: all remaining publishers use platform-specific exceptions 2026-03-31 21:04:39 -03:00
Paulo Castellano
2320c9ae63 refactor: TikTok, YouTube, Facebook publishers use platform exceptions 2026-03-31 20:52:32 -03:00
Paulo Castellano
21cd95d512 refactor: InstagramPublisher uses InstagramPublishException 2026-03-31 20:47:05 -03:00
Paulo Castellano
6886767f9a feat: PublishToSocialPlatform catches SocialPublishException 2026-03-31 20:45:41 -03:00
Paulo Castellano
92ef7428b1 feat: add LinkedIn, X, Threads publish exceptions 2026-03-31 20:43:21 -03:00
Paulo Castellano
9999335da6 feat: add Pinterest, Bluesky, Mastodon publish exceptions 2026-03-31 20:43:13 -03:00
Paulo Castellano
6587c76bc2 feat: add InstagramPublishException with 25 error codes 2026-03-31 20:37:52 -03:00
Paulo Castellano
c3c51d4ccd feat: add ErrorCategory enum and SocialPublishException base class 2026-03-31 20:34:41 -03:00
Paulo Castellano
5e5a15e796 docs: add image resize per platform implementation plan 2026-03-31 20:30:30 -03:00
Paulo Castellano
d081a118b9 docs: add social error mapping implementation plan 2026-03-31 20:23:11 -03:00
Paulo Castellano
cc94d65be8 docs: update image/video specs with verified official sources 2026-03-31 20:19:07 -03:00
Paulo Castellano
56ef30e14c docs: add image resize per platform design spec 2026-03-31 20:03:05 -03:00
Paulo Castellano
d23a9ce923 docs: add complete error codes for all 10 platforms from official docs 2026-03-31 19:59:33 -03:00
Paulo Castellano
7c0c8214f6 docs: update Instagram error codes from official Meta docs 2026-03-31 19:41:47 -03:00
Paulo Castellano
fdfa62ed9b docs: update error mapping spec to follow Laravel 13 conventions 2026-03-31 19:39:46 -03:00
Paulo Castellano
68cf8d9eaa docs: add social error mapping design spec 2026-03-31 19:34:34 -03:00
Paulo Castellano
9f3b8e547a fix: overhaul social publishing — validation, uploads, token refresh
- Fix UpdatePostRequest missing content_type, synced, meta fields
  (content_type was silently dropped, causing Instagram Reels to post as Feed)
- Create API FormRequests (StorePostRequest, UpdatePostRequest) replacing inline validation
- Fix syntax errors in all publishers ($media->isVideo() missing variable)
- Fix Instagram Feed with single video calling publishSingleImage instead of publishReel
- Fix TikTok hardcoded SELF_ONLY privacy — now queries creator_info API
- Refactor YouTubePublisher to use google/apiclient SDK with chunked resumable upload
- Fix all publishers using file_get_contents for large videos (memory overflow)
  — X, LinkedIn, LinkedInPage, Pinterest, Bluesky, Mastodon now use temp file + stream
- Fix Media::isVideo/isImage to use mime_type instead of extension
- Fix Threads not saving refresh_token (was null, now saves access_token)
- Add Instagram token refresh to publisher and ConnectionVerifier
- Fix PublishToSocialPlatform job: tries 3→1 (prevents duplicate uploads),
  timeout 60→600s, added failed() method for cleanup
- Increase Horizon worker timeout 60→630s, Redis retry_after 90→660s
- Increase upload limit 500MB→1GB
- Add mastodon to getDefaultContentType in Edit.vue
2026-03-31 19:25:19 -03:00
Paulo Castellano
bb6d0a2678 fix: Stripe webhook setup completion, notifications routing, billing UI
- Fix StripeEventListener: mark setup as Completed when subscription.created webhook fires
- Fix notifications routes: move outside subscribed middleware (non-critical feature)
- Fix NotificationBell: guard response.ok before parsing JSON
- Fix StripeEventListener: use data_get() for payload access
- Rewrite billing page to use SettingsLayout with download buttons on invoices
- Remove duplicate Unit/Listeners/StripeEventListenerTest (consolidated into Feature)
- Add comprehensive Stripe webhook tests (14 scenarios: happy path, setup transitions, edge cases, error handling)
- Update billing i18n: remove "no credit card" text, add status key
- Move auth layout logo to top-left corner
- Redesign onboarding Role page with compact list layout
- Add persona i18n translations (EN, PT-BR, ES)
- Update README with API, MCP, tech stack, quick start
2026-03-31 13:52:36 -03:00
Paulo Castellano
d48b508ab3 fix: reorder CI steps — env before composer, key after 2026-03-31 12:08:04 -03:00
Paulo Castellano
2691bf172c fix: copy .env.ci before composer install in CI 2026-03-31 12:07:15 -03:00
Paulo Castellano
35c88e798a fix: correct Upload.php filename case for Linux CI 2026-03-31 12:01:48 -03:00
Paulo Castellano
d57b39028e docs: escape asterisk in mcp-development description and fix indentation in CLAUDE.md 2026-03-31 11:46:14 -03:00
Paulo Castellano
176929aa12 chore: reverting domains 2026-03-31 11:35:49 -03:00
Paulo Castellano
c149eda2b0 fix: resolve ESLint errors and cleanup unused code
- Remove unused imports (trans, postsIndex, BreadcrumbItemType, workspaceSettings)
- Remove unused variables (pageDescription, selectedLabels, _progress, props)
- Fix duplicate key: rename preferences import to preferencesRoute
- Remove @unovis ambient declarations (packages now installed)
- Fix import order in Wayfinder-generated routes
2026-03-31 10:26:44 -03:00
Paulo Castellano
6721c623ef chore: update boost skills and config 2026-03-31 09:36:09 -03:00
Paulo Castellano
07ddedceae fix: resolve all TypeScript errors
- Fix Auth type: add currentWorkspace, workspaces, FlashData
- Fix User.id type: number → string (UUID)
- Fix trans() number params: wrap with String()
- Fix debounce NodeJS.Timeout → ReturnType<typeof setTimeout>
- Fix DatePicker name prop: required → optional
- Fix DatePicker emit typing
- Fix storeStep1 → storeRole import in onboarding/Role
- Fix duplicate id in AcceptInvite interface
- Fix formatDate → formatDateTime in ApiKeys
- Add @unovis/vue and @unovis/ts type declarations
- Install @unovis/vue @unovis/ts dev dependencies
- Add type casts for Inertia/Reka UI component props
2026-03-31 09:34:39 -03:00
Paulo Castellano
c020419db1 feat: social account toggle action, API, MCP + full test coverage
- Extract ToggleSocialAccount action from SocialController
- Add API endpoints: GET /social-accounts, PUT /social-accounts/{id}/toggle
- Add MCP tools: ListSocialAccountsTool, ToggleSocialAccountTool
- Fix all MCP tools: findOrFail → find + Response::error for graceful errors
- Fix MCP tools using $request->validated() without validate() call
- Fix return types to Response|ResponseFactory for error paths
- Add SocialAccountResource is_active/status fields (no tokens exposed)
- Add 43 MCP tests covering all 18 tools (CRUD, validation, cross-workspace)
- Add API response structure tests for posts, hashtags, labels, workspace
- Add API validation tests for post create/update, api-key expiry, label color
- Add API cross-workspace delete tests for hashtags and labels
- Add app validation tests for hashtag/label update, invite fields, password
- Add auth required tests for notifications, profile delete, api-keys index
- Add media reorder validation tests
2026-03-31 01:42:39 -03:00
Paulo Castellano
74c6442728 refactor: code review fixes — policies, enums, data_get, tests
- 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
2026-03-31 00:40:18 -03:00
Paulo Castellano
7d95fd1efa chore: tracking, gtm and more 2026-03-30 21:32:43 -03:00
Paulo Castellano
843b3991ec chore: posthog, ui, features and more 2026-03-30 21:18:07 -03:00
Paulo Castellano
91ad58cd01 refactor: sidebar active states, notification bell, phone mockup, UI polish
Sidebar:
- Fix double active state: "All" uses excludeActive to skip filter paths
- Add excludeActive option to urlIsActive composable and NavItem type
- Move notification bell next to user menu (icon only, no text)
- Remove Discord from sidebar footer
- Rename "Docs" to "Documentation" in EN

Phone mockup:
- Increase size from 270x585 to 360x780 for better preview

Header & Layout:
- Add center slot to AppHeader (used by Calendar for date title)
- Calendar controls split: left (nav), center (date), right (tabs + new post)
- Remove duplicate New Post button from day view
- Fix month view scroll (remove overflow-hidden)

UI:
- Move action buttons to header-right: posts, hashtags, labels
- Settings breadcrumbs: "Settings > Profile" pattern for all pages
- Add Cancel button to hashtags create/edit dialogs
- Add common.cancel i18n key for reuse
- Social accounts grid: use shadcn Button ghost for actions

All 753 tests passing.
2026-03-30 18:51:04 -03:00
Paulo Castellano
aa7ca8ae21 refactor: notification preferences, header slots, calendar layout, UI polish
Notification preferences:
- Create notification_preferences table (post_published, post_failed,
  account_disconnected booleans per user)
- NotificationPreferenceController with firstOrCreate on first visit
- SendNotification job respects email preferences before sending
- Settings page with toggle switches, i18n in 3 languages
- 8 new tests for preferences (controller + wantsEmailFor + job integration)

Post published notification:
- PostPublished mail + maizzle template
- Notify owner on successful publish via SendNotification job
- PostPublished type added to notification enum

Header & Layout:
- Rename AppSidebarHeader to AppHeader with left/center/right slots
- showSidebarTrigger prop to hide sidebar toggle
- Calendar: controls in header (left: nav, center: date, right: tabs + new post)
- Fixed header with scrollable content (flex h-screen pattern)
- fullWidth pages use overflow-y-auto (fixes month view scroll)

UI improvements:
- Action buttons moved to header-right: posts, hashtags, labels
- Settings breadcrumbs: "Settings > Profile" pattern
- Calendar: remove duplicate New Post button from day view
- Remove size="sm" from Schedule/Publish buttons
- Remove bg-background from header (inherits from SidebarInset)
- Add Cancel button to labels and hashtags create/edit dialogs
- Add common.cancel i18n key
- Clean up orphaned Calendar breadcrumbs
- Fix SocialAccountsGrid buttons to use shadcn Button ghost

All 753 tests passing.
2026-03-30 18:18:17 -03:00
Paulo Castellano
9b4bdc1ce9 feat: post published notification, notification preferences prep
- Create PostPublished mail + maizzle template for success notifications
- Add PostPublished type to Notification enum
- Notify owner on publish success (email + in-app via SendNotification job)
- Rename AppSidebarHeader to AppHeader with left/right slots
- Fix layout: header fixed, content scrolls (flex h-screen pattern)
- Fix fullWidth pages (calendar, editor) to fill available height
- Fix NotificationBell icon size to match sidebar items
- Fix SocialAccountsGrid buttons to use shadcn Button ghost
- Add pending status i18n key for PostPlatform

All 745 tests passing.
2026-03-30 17:23:36 -03:00