Add a release workflow that builds docker/Dockerfile (production target) for
linux/amd64 and linux/arm64 on native runners and publishes a single
multi-arch manifest to ghcr.io/trypostit/trypost on every v*.*.* tag, tagged
with semver (1.2.3, 1.2, 1) and latest.
Add compose.prod.yaml: a self-host stack that pulls the published image
alongside Postgres and Redis with persistent volumes. Config is inline with
sectioned comments, including a commented S3/R2 block (storage already uses
the default disk, so switching is config-only).
No application code is changed.
Refines the /release slash command to streamline the weekly release process, ensuring better detection of version bumps and integration with the GitHub release API for automated note generation and email drafting.
Replaces semver-by-commit-type detection with sequential numbering.
Patch increments on every release; rolls over to minor at patch=10;
rolls over to major at minor=10. No manual override — every release
is the next number in sequence.
Adds a Claude Code slash command that runs the Friday release flow:
auto-detects semver bump, generates the GitHub release via the native
generate-notes API, drafts a customer-facing email in Cal.com style
(themed prose, no internal references), runs the humanizer skill on the
email prose, and saves mirrors to releases/<version>/.
Facebook Stories do not work reliably with images via the Graph API.
Align validation and publisher with video-only (like Reel), while
Instagram Story continues to accept image or video.
Co-authored-by: Cursor <cursoragent@cursor.com>
Multi-image posts were published as text-only because Laravel sent
attached_media as JSON; Facebook accepts message but drops attachments.
Use asForm() for all FacebookPublisher Graph API calls.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Added consistent imports of the MediaItem type across various components, including FacebookSettings, InstagramSettings, LinkedInSettings, PinterestSettings, PreviewTab, InstagramPreview, and PlatformPreview.
- This change enhances code organization and ensures uniformity in type definitions throughout the project.
Introduced a new environment variable `REQUIRE_CARD_FOR_TRIAL` to control whether a credit card is required for trial signups. Updated the billing configuration to reflect this setting, allowing for more flexible trial management.
- Replaced the `regenerate_image` boolean with a `change_mode` string parameter in the PostImageRegenerator schema, allowing for more granular control over regeneration options.
- Updated methods in RegeneratePostMediaImage to handle the new `change_mode` values: `image_only`, `text_only`, and `both`.
- Enhanced documentation and comments to clarify the new regeneration logic.
- Added tests to verify correct behavior for different regeneration modes, ensuring that text and image changes are handled appropriately.
- Introduced a new `regenerate_image` boolean parameter in the PostImageRegenerator schema to control background image regeneration.
- Updated relevant methods in RegeneratePostMediaImage and TemplateImageGenerator to utilize the new parameter for reusing existing backgrounds when appropriate.
- Enhanced documentation and comments to clarify the usage of the `regenerate_image` option.
- Added tests to ensure correct behavior when reusing background images.
- Replaced custom regeneration logic with a composable for improved organization and reusability.
- Streamlined state management and error handling, enhancing clarity and maintainability.
- Removed unused imports and interfaces, reducing code complexity and improving readability.
- Updated computed properties for better form submission validation and user experience.
- Removed the PostStatusGuard class and replaced its usage with the new PostStatusRules utility across multiple controllers and actions, enhancing code organization and maintainability.
- Updated error message handling to utilize the centralized method in PostStatusRules, ensuring consistency in user feedback.
- Deleted associated tests for PostStatusGuard, reflecting the removal of the class.
- Replaced direct status checks in multiple controllers and actions with the PostStatusGuard utility, improving code readability and maintainability.
- Updated error messages to utilize a centralized method for consistency across the application.
- Removed the BrandImagePalette class, consolidating color resolution logic into the AiImageClient for better organization and type safety.
- Improved type definitions for regeneration status and event handling, increasing clarity and maintainability.
- Streamlined the regeneration result handling by introducing a dedicated function to manage success and error states.
- Added computed properties to optimize form submission logic, ensuring better user experience and validation.
- Refactored the subscription logic to improve readability and error handling during media regeneration.
- Refactored the media item interface by moving it to a dedicated type file, enhancing code organization and reusability across components.
- Updated various components to import the new MediaItem type, ensuring consistency and reducing redundancy in type definitions.
- Improved the RegeneratePostMediaImage job by optimizing the media regeneration process and enhancing error handling for better reliability.
- Added guidelines for AI agents to avoid embedding prompts in PHP and to store them in Blade files under `resources/views/prompts/`.
- Updated `PostImageRegenerator` to render prompts using Blade instead of heredocs, improving maintainability and consistency with project standards.
- Enhanced documentation in `CLAUDE.md` and `.cursor/rules` files to reflect these changes.
Let users adjust AI-generated slides in place via async job and Echo, while applying workspace brand, background, and text colors to image prompts. Autofill swaps site text/background colors for the image palette, and regeneration is blocked on finalized posts with safer job cleanup.
Co-authored-by: Cursor <cursoragent@cursor.com>
Keep the trial card requirement switch as a plain boolean in config/trypost.php so changing the app flow is a single in-repo config edit without env wiring.
Co-authored-by: Cursor <cursoragent@cursor.com>
Add a trypost config toggle to switch between card-required checkout trials and no-card signup trials, and wire signup, checkout, access gating, UI copy, and tests to both modes.
Co-authored-by: Cursor <cursoragent@cursor.com>
Show the checkout-based trial duration again on the subscribe page and rename the signup billing test file so it matches the current no-trial-at-signup behavior.
Co-authored-by: Cursor <cursoragent@cursor.com>
Revert the no-card signup trial flow so access depends on a Stripe subscription trial started at checkout, preventing app access before a payment method is collected.
Co-authored-by: Cursor <cursoragent@cursor.com>
Refactor the user identification process by removing unnecessary type casting for user ID and account ID. This change enhances code readability and maintains functionality for syncing account usage.
Use Account::postsCountCacheKey everywhere, avoid findOrFail when syncing
post deletes, dispatch SyncAccountUsage after DeleteWorkspace when enabled,
and add coverage for the new paths.
Co-authored-by: Cursor <cursoragent@cursor.com>
Parse datetime-local values in the user timezone before converting to UTC,
matching formatUtcForDateTimeLocalInput. Fix ESLint import order in usePostCompliance.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Introduced a new translation key for future date selection prompts in English, Spanish, and Portuguese.
- Implemented logic to disable the confirm button and display a warning message when a past date is selected in the PickTimePopover component.
- Updated date formatting utility to handle UTC dates for HTML datetime-local inputs.
Pull the variant-snap branch out of togglePlatform into a named
helper with guard clauses. togglePlatform now reads top-down:
lock check → deselect short-circuit → snap → select.
Pulls ~200 lines of media/platform/length compliance and tooltip
derivation into composables/usePostCompliance.ts. Edit.vue is now
focused on state, save logic and event handlers; PLATFORM_VARIANTS
and the per-content-type media-rule check are exposed from the
composable for togglePlatform.
- Add separate canDelete predicate in Index.vue that includes Failed —
the previous EDITABLE_STATUSES gating hid the delete button for
failed posts even though the backend allows deleting them.
- Edit.vue Echo handler navigates to /show when an in-page real-time
status update transitions the post into a read-only state, instead
of leaving the user on a stuck readonly editor.
- FacebookPublisher: stop using empty() for content checks (treats
literal "0" as empty) — compare explicitly against null and "".
- Update terminal-state error messages in API + MCP update tool to
reflect the broadened guard (no longer Published-only). Adjust the
matching test assertion.
- Drop 'failed' from EDITABLE_STATUSES in Index.vue and Calendar.vue
so failed posts link directly to /show instead of /edit (which now
redirects).
- Replace remaining 'scheduled'/'publishing' literals in
PostEditorHeader.vue with the PostStatus enum.
- Include Failed in PostEditorHeader's READONLY_STATUSES to match
Edit.vue.
- Split PLATFORM_VARIANTS by Platform key (Platform.LinkedInPage and
Platform.InstagramFacebook were missing; page content types were
grouped under the wrong personal-LinkedIn key).