2026-04-15 23:10:45 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers\App;
|
|
|
|
|
|
|
|
|
|
use App\Events\PostCommentCreated;
|
feat: complete AI assistant with custom services and brand config
Baseline snapshot of custom AI implementation before Laravel AI SDK migration.
Includes:
- Custom services: GeminiTextGenerationService, TextGenerationService (OpenAI), ImageGenerationService, AudioGenerationService, VideoGenerationService
- IntentDetector for content moderation via keyword matching
- AI enums: Intent, Orientation, UsageType
- Blade prompt templates: system.blade.php, image.blade.php, video.blade.php
- AiMessage with content_html accessor (markdown rendering)
- AiUsageLog for monthly quota tracking per account
- PostAssistantController with regex-based [GENERATE_*] parsing
- WritingAssistantTab with markdown rendering, add-to-post, attachments
- Workspace brand fields (name, description, tone, voice_notes) in system prompt
- Session state block injected into prompts (thread counts, quota remaining)
- AttachmentCollector pattern will replace the regex approach in Phase 2
- Post comments with replies, emoji reactions, real-time via Echo
- Assets page with Unsplash + Giphy integrations
2026-04-16 12:25:08 +00:00
|
|
|
use App\Http\Requests\App\PostComment\ReactPostCommentRequest;
|
|
|
|
|
use App\Http\Requests\App\PostComment\StorePostCommentRequest;
|
|
|
|
|
use App\Http\Requests\App\PostComment\UpdatePostCommentRequest;
|
2026-04-15 23:10:45 +00:00
|
|
|
use App\Models\Post;
|
|
|
|
|
use App\Models\PostComment;
|
|
|
|
|
use Illuminate\Http\JsonResponse;
|
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
|
|
|
|
|
|
class PostCommentController extends Controller
|
|
|
|
|
{
|
|
|
|
|
public function index(Request $request, Post $post): JsonResponse
|
|
|
|
|
{
|
|
|
|
|
$workspace = $request->user()->currentWorkspace;
|
|
|
|
|
|
|
|
|
|
if ($post->workspace_id !== $workspace->id) {
|
|
|
|
|
abort(Response::HTTP_FORBIDDEN);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$comments = $post->comments()
|
|
|
|
|
->whereNull('parent_id')
|
|
|
|
|
->with(['user', 'replies.user'])
|
|
|
|
|
->latest()
|
|
|
|
|
->paginate(config('app.pagination.default'));
|
|
|
|
|
|
|
|
|
|
return response()->json($comments);
|
|
|
|
|
}
|
|
|
|
|
|
feat: complete AI assistant with custom services and brand config
Baseline snapshot of custom AI implementation before Laravel AI SDK migration.
Includes:
- Custom services: GeminiTextGenerationService, TextGenerationService (OpenAI), ImageGenerationService, AudioGenerationService, VideoGenerationService
- IntentDetector for content moderation via keyword matching
- AI enums: Intent, Orientation, UsageType
- Blade prompt templates: system.blade.php, image.blade.php, video.blade.php
- AiMessage with content_html accessor (markdown rendering)
- AiUsageLog for monthly quota tracking per account
- PostAssistantController with regex-based [GENERATE_*] parsing
- WritingAssistantTab with markdown rendering, add-to-post, attachments
- Workspace brand fields (name, description, tone, voice_notes) in system prompt
- Session state block injected into prompts (thread counts, quota remaining)
- AttachmentCollector pattern will replace the regex approach in Phase 2
- Post comments with replies, emoji reactions, real-time via Echo
- Assets page with Unsplash + Giphy integrations
2026-04-16 12:25:08 +00:00
|
|
|
public function store(StorePostCommentRequest $request, Post $post): JsonResponse
|
2026-04-15 23:10:45 +00:00
|
|
|
{
|
|
|
|
|
$workspace = $request->user()->currentWorkspace;
|
|
|
|
|
|
|
|
|
|
if ($post->workspace_id !== $workspace->id) {
|
|
|
|
|
abort(Response::HTTP_FORBIDDEN);
|
|
|
|
|
}
|
|
|
|
|
|
feat: complete AI assistant with custom services and brand config
Baseline snapshot of custom AI implementation before Laravel AI SDK migration.
Includes:
- Custom services: GeminiTextGenerationService, TextGenerationService (OpenAI), ImageGenerationService, AudioGenerationService, VideoGenerationService
- IntentDetector for content moderation via keyword matching
- AI enums: Intent, Orientation, UsageType
- Blade prompt templates: system.blade.php, image.blade.php, video.blade.php
- AiMessage with content_html accessor (markdown rendering)
- AiUsageLog for monthly quota tracking per account
- PostAssistantController with regex-based [GENERATE_*] parsing
- WritingAssistantTab with markdown rendering, add-to-post, attachments
- Workspace brand fields (name, description, tone, voice_notes) in system prompt
- Session state block injected into prompts (thread counts, quota remaining)
- AttachmentCollector pattern will replace the regex approach in Phase 2
- Post comments with replies, emoji reactions, real-time via Echo
- Assets page with Unsplash + Giphy integrations
2026-04-16 12:25:08 +00:00
|
|
|
$validated = $request->validated();
|
2026-04-15 23:10:45 +00:00
|
|
|
|
|
|
|
|
if (data_get($validated, 'parent_id')) {
|
feat: complete AI assistant with custom services and brand config
Baseline snapshot of custom AI implementation before Laravel AI SDK migration.
Includes:
- Custom services: GeminiTextGenerationService, TextGenerationService (OpenAI), ImageGenerationService, AudioGenerationService, VideoGenerationService
- IntentDetector for content moderation via keyword matching
- AI enums: Intent, Orientation, UsageType
- Blade prompt templates: system.blade.php, image.blade.php, video.blade.php
- AiMessage with content_html accessor (markdown rendering)
- AiUsageLog for monthly quota tracking per account
- PostAssistantController with regex-based [GENERATE_*] parsing
- WritingAssistantTab with markdown rendering, add-to-post, attachments
- Workspace brand fields (name, description, tone, voice_notes) in system prompt
- Session state block injected into prompts (thread counts, quota remaining)
- AttachmentCollector pattern will replace the regex approach in Phase 2
- Post comments with replies, emoji reactions, real-time via Echo
- Assets page with Unsplash + Giphy integrations
2026-04-16 12:25:08 +00:00
|
|
|
$parent = PostComment::where('id', data_get($validated, 'parent_id'))
|
|
|
|
|
->where('post_id', $post->id)
|
|
|
|
|
->first();
|
|
|
|
|
|
|
|
|
|
if (! $parent) {
|
|
|
|
|
abort(Response::HTTP_NOT_FOUND);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($parent->parent_id !== null) {
|
2026-04-15 23:10:45 +00:00
|
|
|
abort(Response::HTTP_UNPROCESSABLE_ENTITY, 'Cannot reply to a reply.');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$comment = $post->comments()->create([
|
|
|
|
|
'user_id' => $request->user()->id,
|
|
|
|
|
'parent_id' => data_get($validated, 'parent_id'),
|
|
|
|
|
'body' => data_get($validated, 'body'),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$comment->load('user');
|
|
|
|
|
|
|
|
|
|
PostCommentCreated::dispatch($comment);
|
|
|
|
|
|
|
|
|
|
return response()->json($comment, Response::HTTP_CREATED);
|
|
|
|
|
}
|
|
|
|
|
|
feat: complete AI assistant with custom services and brand config
Baseline snapshot of custom AI implementation before Laravel AI SDK migration.
Includes:
- Custom services: GeminiTextGenerationService, TextGenerationService (OpenAI), ImageGenerationService, AudioGenerationService, VideoGenerationService
- IntentDetector for content moderation via keyword matching
- AI enums: Intent, Orientation, UsageType
- Blade prompt templates: system.blade.php, image.blade.php, video.blade.php
- AiMessage with content_html accessor (markdown rendering)
- AiUsageLog for monthly quota tracking per account
- PostAssistantController with regex-based [GENERATE_*] parsing
- WritingAssistantTab with markdown rendering, add-to-post, attachments
- Workspace brand fields (name, description, tone, voice_notes) in system prompt
- Session state block injected into prompts (thread counts, quota remaining)
- AttachmentCollector pattern will replace the regex approach in Phase 2
- Post comments with replies, emoji reactions, real-time via Echo
- Assets page with Unsplash + Giphy integrations
2026-04-16 12:25:08 +00:00
|
|
|
public function update(UpdatePostCommentRequest $request, Post $post, PostComment $comment): JsonResponse
|
2026-04-15 23:10:45 +00:00
|
|
|
{
|
feat: complete AI assistant with custom services and brand config
Baseline snapshot of custom AI implementation before Laravel AI SDK migration.
Includes:
- Custom services: GeminiTextGenerationService, TextGenerationService (OpenAI), ImageGenerationService, AudioGenerationService, VideoGenerationService
- IntentDetector for content moderation via keyword matching
- AI enums: Intent, Orientation, UsageType
- Blade prompt templates: system.blade.php, image.blade.php, video.blade.php
- AiMessage with content_html accessor (markdown rendering)
- AiUsageLog for monthly quota tracking per account
- PostAssistantController with regex-based [GENERATE_*] parsing
- WritingAssistantTab with markdown rendering, add-to-post, attachments
- Workspace brand fields (name, description, tone, voice_notes) in system prompt
- Session state block injected into prompts (thread counts, quota remaining)
- AttachmentCollector pattern will replace the regex approach in Phase 2
- Post comments with replies, emoji reactions, real-time via Echo
- Assets page with Unsplash + Giphy integrations
2026-04-16 12:25:08 +00:00
|
|
|
if ($comment->post_id !== $post->id) {
|
|
|
|
|
abort(Response::HTTP_NOT_FOUND);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 23:10:45 +00:00
|
|
|
if ($comment->user_id !== $request->user()->id) {
|
|
|
|
|
abort(Response::HTTP_FORBIDDEN);
|
|
|
|
|
}
|
|
|
|
|
|
feat: complete AI assistant with custom services and brand config
Baseline snapshot of custom AI implementation before Laravel AI SDK migration.
Includes:
- Custom services: GeminiTextGenerationService, TextGenerationService (OpenAI), ImageGenerationService, AudioGenerationService, VideoGenerationService
- IntentDetector for content moderation via keyword matching
- AI enums: Intent, Orientation, UsageType
- Blade prompt templates: system.blade.php, image.blade.php, video.blade.php
- AiMessage with content_html accessor (markdown rendering)
- AiUsageLog for monthly quota tracking per account
- PostAssistantController with regex-based [GENERATE_*] parsing
- WritingAssistantTab with markdown rendering, add-to-post, attachments
- Workspace brand fields (name, description, tone, voice_notes) in system prompt
- Session state block injected into prompts (thread counts, quota remaining)
- AttachmentCollector pattern will replace the regex approach in Phase 2
- Post comments with replies, emoji reactions, real-time via Echo
- Assets page with Unsplash + Giphy integrations
2026-04-16 12:25:08 +00:00
|
|
|
$workspace = $request->user()->currentWorkspace;
|
|
|
|
|
if ($comment->post->workspace_id !== $workspace->id) {
|
|
|
|
|
abort(Response::HTTP_FORBIDDEN);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$validated = $request->validated();
|
2026-04-15 23:10:45 +00:00
|
|
|
|
|
|
|
|
$comment->update(['body' => data_get($validated, 'body')]);
|
|
|
|
|
|
|
|
|
|
return response()->json($comment);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function destroy(Request $request, Post $post, PostComment $comment): JsonResponse
|
|
|
|
|
{
|
feat: complete AI assistant with custom services and brand config
Baseline snapshot of custom AI implementation before Laravel AI SDK migration.
Includes:
- Custom services: GeminiTextGenerationService, TextGenerationService (OpenAI), ImageGenerationService, AudioGenerationService, VideoGenerationService
- IntentDetector for content moderation via keyword matching
- AI enums: Intent, Orientation, UsageType
- Blade prompt templates: system.blade.php, image.blade.php, video.blade.php
- AiMessage with content_html accessor (markdown rendering)
- AiUsageLog for monthly quota tracking per account
- PostAssistantController with regex-based [GENERATE_*] parsing
- WritingAssistantTab with markdown rendering, add-to-post, attachments
- Workspace brand fields (name, description, tone, voice_notes) in system prompt
- Session state block injected into prompts (thread counts, quota remaining)
- AttachmentCollector pattern will replace the regex approach in Phase 2
- Post comments with replies, emoji reactions, real-time via Echo
- Assets page with Unsplash + Giphy integrations
2026-04-16 12:25:08 +00:00
|
|
|
if ($comment->post_id !== $post->id) {
|
|
|
|
|
abort(Response::HTTP_NOT_FOUND);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 23:10:45 +00:00
|
|
|
if ($comment->user_id !== $request->user()->id) {
|
|
|
|
|
abort(Response::HTTP_FORBIDDEN);
|
|
|
|
|
}
|
|
|
|
|
|
feat: complete AI assistant with custom services and brand config
Baseline snapshot of custom AI implementation before Laravel AI SDK migration.
Includes:
- Custom services: GeminiTextGenerationService, TextGenerationService (OpenAI), ImageGenerationService, AudioGenerationService, VideoGenerationService
- IntentDetector for content moderation via keyword matching
- AI enums: Intent, Orientation, UsageType
- Blade prompt templates: system.blade.php, image.blade.php, video.blade.php
- AiMessage with content_html accessor (markdown rendering)
- AiUsageLog for monthly quota tracking per account
- PostAssistantController with regex-based [GENERATE_*] parsing
- WritingAssistantTab with markdown rendering, add-to-post, attachments
- Workspace brand fields (name, description, tone, voice_notes) in system prompt
- Session state block injected into prompts (thread counts, quota remaining)
- AttachmentCollector pattern will replace the regex approach in Phase 2
- Post comments with replies, emoji reactions, real-time via Echo
- Assets page with Unsplash + Giphy integrations
2026-04-16 12:25:08 +00:00
|
|
|
$workspace = $request->user()->currentWorkspace;
|
|
|
|
|
if ($comment->post->workspace_id !== $workspace->id) {
|
|
|
|
|
abort(Response::HTTP_FORBIDDEN);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 23:10:45 +00:00
|
|
|
$comment->delete();
|
|
|
|
|
|
|
|
|
|
return response()->json(null, Response::HTTP_NO_CONTENT);
|
|
|
|
|
}
|
|
|
|
|
|
feat: complete AI assistant with custom services and brand config
Baseline snapshot of custom AI implementation before Laravel AI SDK migration.
Includes:
- Custom services: GeminiTextGenerationService, TextGenerationService (OpenAI), ImageGenerationService, AudioGenerationService, VideoGenerationService
- IntentDetector for content moderation via keyword matching
- AI enums: Intent, Orientation, UsageType
- Blade prompt templates: system.blade.php, image.blade.php, video.blade.php
- AiMessage with content_html accessor (markdown rendering)
- AiUsageLog for monthly quota tracking per account
- PostAssistantController with regex-based [GENERATE_*] parsing
- WritingAssistantTab with markdown rendering, add-to-post, attachments
- Workspace brand fields (name, description, tone, voice_notes) in system prompt
- Session state block injected into prompts (thread counts, quota remaining)
- AttachmentCollector pattern will replace the regex approach in Phase 2
- Post comments with replies, emoji reactions, real-time via Echo
- Assets page with Unsplash + Giphy integrations
2026-04-16 12:25:08 +00:00
|
|
|
public function react(ReactPostCommentRequest $request, Post $post, PostComment $comment): JsonResponse
|
2026-04-15 23:10:45 +00:00
|
|
|
{
|
feat: complete AI assistant with custom services and brand config
Baseline snapshot of custom AI implementation before Laravel AI SDK migration.
Includes:
- Custom services: GeminiTextGenerationService, TextGenerationService (OpenAI), ImageGenerationService, AudioGenerationService, VideoGenerationService
- IntentDetector for content moderation via keyword matching
- AI enums: Intent, Orientation, UsageType
- Blade prompt templates: system.blade.php, image.blade.php, video.blade.php
- AiMessage with content_html accessor (markdown rendering)
- AiUsageLog for monthly quota tracking per account
- PostAssistantController with regex-based [GENERATE_*] parsing
- WritingAssistantTab with markdown rendering, add-to-post, attachments
- Workspace brand fields (name, description, tone, voice_notes) in system prompt
- Session state block injected into prompts (thread counts, quota remaining)
- AttachmentCollector pattern will replace the regex approach in Phase 2
- Post comments with replies, emoji reactions, real-time via Echo
- Assets page with Unsplash + Giphy integrations
2026-04-16 12:25:08 +00:00
|
|
|
if ($comment->post_id !== $post->id) {
|
|
|
|
|
abort(Response::HTTP_NOT_FOUND);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 23:10:45 +00:00
|
|
|
$workspace = $request->user()->currentWorkspace;
|
|
|
|
|
|
|
|
|
|
if ($post->workspace_id !== $workspace->id) {
|
|
|
|
|
abort(Response::HTTP_FORBIDDEN);
|
|
|
|
|
}
|
|
|
|
|
|
feat: complete AI assistant with custom services and brand config
Baseline snapshot of custom AI implementation before Laravel AI SDK migration.
Includes:
- Custom services: GeminiTextGenerationService, TextGenerationService (OpenAI), ImageGenerationService, AudioGenerationService, VideoGenerationService
- IntentDetector for content moderation via keyword matching
- AI enums: Intent, Orientation, UsageType
- Blade prompt templates: system.blade.php, image.blade.php, video.blade.php
- AiMessage with content_html accessor (markdown rendering)
- AiUsageLog for monthly quota tracking per account
- PostAssistantController with regex-based [GENERATE_*] parsing
- WritingAssistantTab with markdown rendering, add-to-post, attachments
- Workspace brand fields (name, description, tone, voice_notes) in system prompt
- Session state block injected into prompts (thread counts, quota remaining)
- AttachmentCollector pattern will replace the regex approach in Phase 2
- Post comments with replies, emoji reactions, real-time via Echo
- Assets page with Unsplash + Giphy integrations
2026-04-16 12:25:08 +00:00
|
|
|
$validated = $request->validated();
|
2026-04-15 23:10:45 +00:00
|
|
|
|
|
|
|
|
$comment->addReaction($request->user()->id, data_get($validated, 'emoji'));
|
|
|
|
|
|
|
|
|
|
return response()->json($comment->fresh());
|
|
|
|
|
}
|
|
|
|
|
}
|