2026-04-16 00:06:06 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
namespace App\Models;
|
|
|
|
|
|
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\Enums\Ai\UsageType;
|
feat: per-workspace pricing, onboarding, and billing overhaul
Pricing
- Bill per workspace ($12/mo or $120/yr each); Stripe quantity tracks the
workspace count and syncs on workspace create/delete.
- 2,500 AI credits per workspace, pooled at the account level; monthly reset
on the billing anniversary, annual granted upfront (no rollover).
- One social account per network per workspace; remove all count-based limits
(workspace/social/member) and the legacy plan tiers (single Workspace plan).
Onboarding (cloud only: SELF_HOSTED=false + PostHog)
- Replace the /subscribe plan picker with /onboarding persona selection
(Creator/Freelancer/Startup/Agency/Small business/Other), saved on the user
(users.persona) and mirrored to PostHog, then Stripe Checkout on the monthly
price. 8-day trial so Stripe displays 7.
Billing screen
- Remove the Change Plan dialog (dead with a single plan); add an annual-upgrade
banner for monthly subscribers (swapToYearly).
- Current-plan card shows the workspace count instead of the plan name.
System AI
- Brand analyzer / workspace autofill is always allowed and never debits credits
(system feature, not the user's usage).
Self-hosted (SELF_HOSTED=true) bypasses all billing, credit, limit, network,
and onboarding logic.
2026-06-21 23:40:03 +00:00
|
|
|
use Carbon\CarbonInterface;
|
2026-04-16 00:06:06 +00:00
|
|
|
use Database\Factories\AiUsageLogFactory;
|
|
|
|
|
use Illuminate\Database\Eloquent\Concerns\HasUuids;
|
|
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
|
|
|
|
|
|
class AiUsageLog extends Model
|
|
|
|
|
{
|
|
|
|
|
/** @use HasFactory<AiUsageLogFactory> */
|
|
|
|
|
use HasFactory, HasUuids;
|
|
|
|
|
|
2026-04-16 00:23:13 +00:00
|
|
|
protected $table = 'workspace_ai_usages';
|
|
|
|
|
|
2026-04-16 00:06:06 +00:00
|
|
|
protected $fillable = [
|
|
|
|
|
'account_id',
|
|
|
|
|
'workspace_id',
|
|
|
|
|
'user_id',
|
|
|
|
|
'post_id',
|
|
|
|
|
'type',
|
|
|
|
|
'provider',
|
2026-05-03 22:36:26 +00:00
|
|
|
'model',
|
|
|
|
|
'prompt_tokens',
|
|
|
|
|
'completion_tokens',
|
|
|
|
|
'total_tokens',
|
|
|
|
|
'credits',
|
2026-04-16 00:06:06 +00:00
|
|
|
'metadata',
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
protected function casts(): array
|
|
|
|
|
{
|
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
|
|
|
return [
|
|
|
|
|
'type' => UsageType::class,
|
2026-05-03 22:36:26 +00:00
|
|
|
'prompt_tokens' => 'integer',
|
|
|
|
|
'completion_tokens' => 'integer',
|
|
|
|
|
'total_tokens' => 'integer',
|
|
|
|
|
'credits' => 'integer',
|
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
|
|
|
'metadata' => 'array',
|
|
|
|
|
];
|
2026-04-16 00:06:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function account(): BelongsTo
|
|
|
|
|
{
|
|
|
|
|
return $this->belongsTo(Account::class);
|
|
|
|
|
}
|
|
|
|
|
|
feat: per-workspace pricing, onboarding, and billing overhaul
Pricing
- Bill per workspace ($12/mo or $120/yr each); Stripe quantity tracks the
workspace count and syncs on workspace create/delete.
- 2,500 AI credits per workspace, pooled at the account level; monthly reset
on the billing anniversary, annual granted upfront (no rollover).
- One social account per network per workspace; remove all count-based limits
(workspace/social/member) and the legacy plan tiers (single Workspace plan).
Onboarding (cloud only: SELF_HOSTED=false + PostHog)
- Replace the /subscribe plan picker with /onboarding persona selection
(Creator/Freelancer/Startup/Agency/Small business/Other), saved on the user
(users.persona) and mirrored to PostHog, then Stripe Checkout on the monthly
price. 8-day trial so Stripe displays 7.
Billing screen
- Remove the Change Plan dialog (dead with a single plan); add an annual-upgrade
banner for monthly subscribers (swapToYearly).
- Current-plan card shows the workspace count instead of the plan name.
System AI
- Brand analyzer / workspace autofill is always allowed and never debits credits
(system feature, not the user's usage).
Self-hosted (SELF_HOSTED=true) bypasses all billing, credit, limit, network,
and onboarding logic.
2026-06-21 23:40:03 +00:00
|
|
|
public static function creditsUsedBetween(string $accountId, CarbonInterface $start, CarbonInterface $end): int
|
2026-04-16 00:06:06 +00:00
|
|
|
{
|
2026-05-03 22:36:26 +00:00
|
|
|
return (int) static::where('account_id', $accountId)
|
feat: per-workspace pricing, onboarding, and billing overhaul
Pricing
- Bill per workspace ($12/mo or $120/yr each); Stripe quantity tracks the
workspace count and syncs on workspace create/delete.
- 2,500 AI credits per workspace, pooled at the account level; monthly reset
on the billing anniversary, annual granted upfront (no rollover).
- One social account per network per workspace; remove all count-based limits
(workspace/social/member) and the legacy plan tiers (single Workspace plan).
Onboarding (cloud only: SELF_HOSTED=false + PostHog)
- Replace the /subscribe plan picker with /onboarding persona selection
(Creator/Freelancer/Startup/Agency/Small business/Other), saved on the user
(users.persona) and mirrored to PostHog, then Stripe Checkout on the monthly
price. 8-day trial so Stripe displays 7.
Billing screen
- Remove the Change Plan dialog (dead with a single plan); add an annual-upgrade
banner for monthly subscribers (swapToYearly).
- Current-plan card shows the workspace count instead of the plan name.
System AI
- Brand analyzer / workspace autofill is always allowed and never debits credits
(system feature, not the user's usage).
Self-hosted (SELF_HOSTED=true) bypasses all billing, credit, limit, network,
and onboarding logic.
2026-06-21 23:40:03 +00:00
|
|
|
->where('created_at', '>=', $start)
|
|
|
|
|
->where('created_at', '<', $end)
|
2026-05-03 22:36:26 +00:00
|
|
|
->sum('credits');
|
2026-04-16 00:06:06 +00:00
|
|
|
}
|
|
|
|
|
}
|