Commit graph

241 commits

Author SHA1 Message Date
Paulo Castellano
7f491b2c2c feat: add post_comments table, model, and factory 2026-04-15 20:08:16 -03:00
Paulo Castellano
e1965f9f7c feat: integrate Giphy support and add trending endpoints for media assets 2026-04-15 11:02:10 -03:00
Paulo Castellano
0d88ced20b feat: implement asset management system with Unsplash integration and chunked uploads 2026-04-15 10:20:37 -03:00
Paulo Castellano
a8bb44f0e5 fix: self-host billing bypass, Facebook API metrics migration, X token refresh, and duplicate social accounts
- Block all billing/usage/subscribe routes in self-hosted mode (redirect to calendar)
- Hide billing_email field in account settings when self-hosted
- Migrate deprecated Facebook Page Insights metrics to new Media Views API (v25.0)
- Fix X analytics token refresh to use Basic Auth (matching XPublisher/ConnectionVerifier)
- Prevent duplicate social accounts by using updateOrCreate across all OAuth controllers
2026-04-15 09:46:18 -03:00
Paulo Castellano
ded1c998ec feat: redesign billing, onboarding, sidebar, and settings architecture
- Sidebar reorganized: Workspace group (connections, hashtags, labels,
  API keys, settings) and Account group (settings, usage, billing)
- Account group only visible to owner and hidden in self-hosted mode
- Onboarding simplified: role -> account (connect socials) -> completed
  -> redirect to /subscribe. Removed Subscription setup step.
- Subscribe page redesigned with 4 plan cards, monthly/yearly toggle,
  trial info, and per-plan features list
- Billing page redesigned following Sendkit layout (sections with
  sidebar labels)
- Processing page uses usePoll with immediate watch for subscription
  activation
- Cancel URL redirects directly to /subscribe
- Account settings page with name and billing_email (syncs with Stripe)
- Usage page with ring meters for all plan limits
- Settings layout tabs only for user pages (profile, password,
  notifications). Workspace/API keys/billing are standalone pages.
- GoogleAuthButton extracted as reusable component
- WorkspaceRole TypeScript enum for type-safe role checks in frontend
- Trial period changed to 7 days
- Fixed onboarding loop when user confirms email
- All 1101 tests passing
2026-04-15 00:33:38 -03:00
Paulo Castellano
2da15df96c feat: introduce Account entity as billing owner and refactor architecture
- 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
2026-04-14 22:22:04 -03:00
Paulo Castellano
ba27688c59 fix: use date.diffForHumans instead of missing formatDate export 2026-04-14 19:52:14 -03:00
Paulo Castellano
8e6e544ffe feat: move Google login button above email/password form on login and register pages 2026-04-14 19:50:40 -03:00
Paulo Castellano
8caa3d55c7 feat: redesign accounts page with multi-account support
- New card-based layout showing connected accounts with avatar, platform
  badge, brand label, and connection date
- "Add Social" button opens dialog with platform grid for connecting
- Removed unique constraint on workspace_id+platform to allow multiple
  accounts per platform
- Removed "already connected" checks from all 13 OAuth controllers
- Updated tests to verify multi-account connection works
2026-04-14 19:48:35 -03:00
Paulo Castellano
3a98de0482 feat: add brands frontend (sidebar, index page, create/edit dialogs, translations) 2026-04-14 19:22:33 -03:00
Paulo Castellano
e876ba3839 fix: wire inviteMember policy in invite controller and add brand translations 2026-04-14 19:14:41 -03:00
Paulo Castellano
42d5adeb1a refactor: consolidate billing migrations into original files
Instead of separate alter-table migrations, edit the original
create_table migrations directly since we're resetting the database.

- Users table: removed stripe_id, pm_type, pm_last_four, trial_ends_at
- Workspaces table: added plan_id, stripe_id, pm_type, pm_last_four, trial_ends_at
- Subscriptions table: changed user_id FK to workspace_id FK
- Social accounts table: added brand_id FK
- Plans and brands tables ordered before their dependents
- Deleted 5 redundant alter-table migrations
2026-04-14 18:59:43 -03:00
Paulo Castellano
c867faa2ee fix: address code review issues for billing migration 2026-04-14 18:44:47 -03:00
Paulo Castellano
8349b34bc1 feat: enforce plan limits via Pennant in policies 2026-04-14 18:31:13 -03:00
Paulo Castellano
1ff2f93c37 feat: move Billable from User to Workspace with plan support 2026-04-14 18:22:36 -03:00
Paulo Castellano
c107ce3949 feat: create brands with CRUD, policy, and tests 2026-04-14 18:04:41 -03:00
Paulo Castellano
5bc1548423 feat: create PlanSeeder with 4 tiered plans 2026-04-14 17:56:13 -03:00
Paulo Castellano
d235e702cf feat: create plans table, model, and slug enum 2026-04-14 17:53:12 -03:00
Paulo Castellano
bb871ac95c docs: add implementation plan for workspace billing migration 2026-04-14 17:46:40 -03:00
Paulo Castellano
eb22243abf docs: add Laravel Pennant features to billing spec 2026-04-14 17:39:43 -03:00
Paulo Castellano
603c76fa93 docs: add spec for workspace billing, plans and brands migration 2026-04-14 17:38:12 -03:00
Paulo Castellano
450635f53e
Merge pull request #11 from trypost-it/feature/google-auth-toggle
feat: Google Auth toggle — TRYPOST_GOOGLE_AUTH_ENABLED
2026-04-14 14:50:48 -03:00
Paulo Castellano
80c193f69f feat: add localization files and update Instagram-Facebook environment variable key 2026-04-14 14:49:38 -03:00
Paulo Castellano
2fcf0a7e7a fix: update Socialite mocks in social controller tests
The mock shorthand Mockery::mock([...]) was not compatible with the
Socialite facade mock. Replaced with explicit shouldReceive chains
matching each controller's actual Socialite method calls.

Also keeps Google OAuth routes always registered so Wayfinder can
generate TypeScript helpers regardless of GOOGLE_AUTH_ENABLED setting.
2026-04-14 14:44:15 -03:00
Paulo Castellano
1a7af9728f Merge remote-tracking branch 'origin/main' into feature/google-auth-toggle 2026-04-14 14:29:56 -03:00
Paulo Castellano
557507672e fix: keep Google OAuth routes always registered and add tests
Routes must always exist so Wayfinder can generate TypeScript helpers.
The toggle now only controls frontend visibility via Inertia prop.
2026-04-14 14:28:17 -03:00
Paulo Castellano
d94374c31a refactor: remove TRYPOST_ prefix from platform env variables
Standardizes env naming to match existing convention (THREADS_CLIENT_ID,
GOOGLE_AUTH_ENABLED, etc).
2026-04-14 14:19:51 -03:00
Paulo Castellano
25c43a3906 refactor: rename TRYPOST_GOOGLE_AUTH_ENABLED to GOOGLE_AUTH_ENABLED
Aligns with existing Google env naming convention (GOOGLE_AUTH_CALLBACK).
2026-04-14 14:16:34 -03:00
Paulo Castellano
75061679bf
Merge pull request #13 from trypost-it/feature/youtube-analytics
feat: add YouTube Analytics
2026-04-14 14:00:55 -03:00
Paulo Castellano
e46a895844 fix: match skeleton loading count with other analytics components 2026-04-14 13:41:02 -03:00
Paulo Castellano
817d6822b9 refactor: optimize json parsing and add missing test coverage
- Store response JSON once instead of parsing twice
- Add tests for null refresh token and token refresh failure scenarios
2026-04-14 13:36:22 -03:00
Paulo Castellano
4cf601e618 feat: add YouTube Analytics with 7 channel metrics
Integrates YouTube Analytics API v2 to display channel-level metrics
(views, minutes watched, avg view duration, avg view percentage,
subscribers gained/lost, likes) with date range support and caching.
2026-04-14 13:10:27 -03:00
Paulo Castellano
e805a3bdb3 chore: improvements on lang 2026-04-04 09:59:16 -03:00
Paulo Castellano
59380cd58a fix: Instagram analytics baseUrl was duplicating version path for instagram-facebook accounts 2026-04-04 09:46:53 -03:00
Paulo Castellano
0e930d7bb2 fix: add /me API call in Facebook OAuth callbacks to trigger public_profile for Meta app review 2026-04-03 21:21:53 -03:00
Paulo Castellano
c5c36a8aba fix: use publicaly_available_post_id from TikTok status to build video URL 2026-04-02 18:29:56 -03:00
Paulo Castellano
326648d4f9 fix: use asJson() on TikTok HTTP client to send proper JSON body 2026-04-02 18:14:32 -03:00
Paulo Castellano
cb91529964 chore: working 2026-04-02 17:57:06 -03:00
Paulo Castellano
1129205c22 fix: TikTok add missing scopes + send empty body to creator_info endpoint 2026-04-01 15:33:17 -03:00
Paulo Castellano
57df5d5253 feat: add TRYPOST_GOOGLE_AUTH_ENABLED toggle to show/hide Google login on auth pages 2026-04-01 15:27:26 -03:00
Paulo Castellano
6e86b83433
Merge pull request #10 from trypost-it/refactor/actions-subdomain-routes
refactor: single-domain routing, actions, policies, Google login, PostHog, full test coverage
2026-04-01 15:20:51 -03:00
Paulo Castellano
5e3520eadd chore: remove stale lang json files 2026-04-01 15:20:34 -03:00
Paulo Castellano
66d0731090 fix: YouTube requires content text — frontend validation now shows error when content is empty 2026-04-01 15:12:56 -03:00
Paulo Castellano
7aaaf4df4f fix: revert Facebook Reel/Story to URL pull (video_file_chunk as URL) — binary upload was breaking the transfer phase 2026-04-01 15:07:02 -03:00
Paulo Castellano
146bd7b7d2 fix: delete post redirects to posts index instead of back() which causes 404 2026-04-01 15:04:13 -03:00
Paulo Castellano
4e6a2dace1 fix: increase OAuth callback close delay to 5s 2026-04-01 14:55:45 -03:00
Paulo Castellano
da2b7ca9ca fix: Facebook/Instagram/Threads OAuthException type incorrectly treated as token error — now only code 190 triggers TokenExpiredException 2026-04-01 14:33:26 -03:00
Paulo Castellano
fbe49e917f refactor: use Status enum instead of hardcoded string in scheduled_at validation 2026-04-01 14:29:03 -03:00
Paulo Castellano
09533b0f84 fix: scheduled_at after:now only for 'scheduled' status, not 'publishing' (publish now) 2026-04-01 14:28:24 -03:00
Paulo Castellano
0bca140cd9 fix: API scheduled_at validation, redirect allowlist, UUID model_id, UpdatePost transaction, safe resolveModel 2026-04-01 13:21:22 -03:00