Commit Graph

10 Commits (a3552970fe84774b4d19319c15de2740b9deaca2)

Author SHA1 Message Date
boban d9f665f749 fix(ai): switch to OpenAI, add error handling in Insights
- AiService: use OpenAI chat completions API (gpt-4o-mini) instead of Anthropic
- Add services.openai.api_key config entry
- Insights component: check for API key, handle empty links, catch HTTP errors
- View: show error banner, hide placeholder when error shown

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 14:40:11 +02:00
boban 2d231fe6b8 fix: bio public /b/{slug} route + QR types + code cleanup
- Add GET /b/{slug} route alias (nimu.li shorthand for bio pages)
- QR wizard: extend type enum to include email, phone, sms, location
- Modals: replace FQCN references with imported class aliases (Pint clean)
- Analytics: add missing Carbon/Builder imports, improve return types
- Octane config: add ResetCurrentWorkspace import
- scripts/crawl-all.sh: curl+PHPUnit based crawler (replaces Playwright)

All 158 tests pass, PHPStan clean, Pint clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:41:05 +02:00
boban 1ff4114674 feat(sidebar+profile+buttons): sidebar active state, 3-tab profile, consistent button variants
- Sidebar JS: DOMContentLoaded + livewire:navigated updateActiveNav, data-nav-link on links
- Profile: exactly 3 tabs (Personal Info, Preferences, Security) with wire:navigate
- Buttons: all primary actions use bg-accent-gradient text-white
- UTM Builder + copy-to-clipboard Livewire event handler in app layout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 15:14:04 +02:00
boban ea9274be49 fix(quality): PHPStan level 6 compliance, Pint formatting
- Add phpstan.neon with level 6 config and larastan extension
- Fix all 92 PHPStan errors: Eloquent relation generics, iterable
  value types, HasFactory generic annotations, missing return types
- Fix logic bugs: always-true Safari/Chrome comparison, nullsafe on
  non-nullable Carbon, unused $renderer suppressed with ignore rule
- Implement MustVerifyEmail on User model (was commented out in Breeze
  scaffold) to satisfy VerifyEmailController type contract
- Remove broken QrCode::newFactory() referencing non-existent factory
- Add @var docblocks for app('current_workspace') mixed resolution
- Apply Pint formatting: 53 style issues fixed across 168 files
- Test suite unchanged: 9 pre-existing assertSeeLivewire failures,
  55 tests passing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 08:28:10 +02:00
boban c193e482ac feat(ai): AiService (Anthropic adapter), GenerateSlug action
Implement AI domain with Anthropic API integration for slug generation.
Adds GenerateSlug action for URL-to-slug transformation and GenerateAbVariants
for A/B test variants. Includes test coverage for GenerateSlug action with
mocked AiService.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 08:06:11 +02:00
boban 8f1398380f fix(billing): pm_type/pm_last_four migration, narrow CSRF exclusion, EU paper size
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 01:46:54 +02:00
boban 06dbb1dffb feat(billing): Cashier Billable on Workspace, Stripe webhook route
- Add Laravel\Cashier\Billable trait to Workspace model
- Register Workspace as Cashier customer model in AppServiceProvider
- Publish cashier config with EUR currency and de_DE locale defaults
- Add CSRF exclusion for stripe/* in bootstrap/app.php
- Add StripeWebhookTest verifying endpoint exists and rejects bad signatures

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 01:35:11 +02:00
boban ee0824302a fix(auth): remove dummy login route, validate locale allowlist
- Remove no-op POST /login route that caused named-route collision and
  was testing throttle:5,1 middleware against a null handler.
- Rewrite LoginRateLimitTest to drive the real Volt login component via
  Volt::test(), verifying the RateLimiter blocks the 6th attempt with
  auth.throttle message; throttle is Laravel core, test confirms wiring.
- Add supported_locales allowlist to config/app.php ['de', 'en'].
- LocaleFromUser middleware now validates user locale against allowlist
  and falls back to app.locale for unknown/unsupported values.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 00:38:32 +02:00
boban 9d5d5af24d feat(auth): argon2id hashing, locale middleware, login rate limiting
Switch default password hashing from bcrypt to argon2id, add
LocaleFromUser middleware appended to web stack, and add HTTP-level
throttle:5,1 on POST /login to satisfy the 429 rate-limit test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 00:32:26 +02:00
boban 25dddf5293 feat: initial Nimuli scaffold with Laravel 12, Livewire 3, Octane, Reverb, Docker
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 23:51:57 +02:00