Commit graph

18 commits

Author SHA1 Message Date
Vadym Samoilenko
c25d2423a0 fix(enrichment): handle ObjectId/datetime in persona dict before LLM call
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 15:13:38 +01:00
Vadym Samoilenko
604fdb9458 feat(marketplace): full persona page + categories + enrichment script
- GET /api/marketplace/personas/:id — returns all fields of a published persona
- Expand _COPY_FIELDS to include all new schema fields (oceanTraits, scenarios, aiSynthesizedBio, etc.)
- New MarketplacePersonaView page (/marketplace/personas/:id) with full sidebar + tabs
- Preview button navigates to full page instead of opening a summary dialog
- Clicking card body also navigates to persona page
- scripts/enrich_old_personas.py — LLM enrichment for 12 pre-schema personas

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 14:38:42 +01:00
Vadym Samoilenko
c757cdb5ba chore(scripts): seed 7 developer personas for marketplace testing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 17:55:37 +01:00
Vadym Samoilenko
bbbca5bdf8 chore(billing): add backfill script for amount_usd on old purchase transactions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 17:14:39 +01:00
Vadym Samoilenko
9d2f1f2c7d feat: complete AIMPRESS visual rebrand — warm palette, new landing, real dashboard
Some checks failed
Deploy to Production / deploy (push) Failing after 0s
- Replace cyan/violet design tokens with warm dark slate + orange (#E89B3C) palette
- Add Space Grotesk display font; new utilities: .outline-display, .orange-band, .corner-card, .persona-orb
- New brand components: Logo (hexagonal SVG), Header (pill nav + glass blur), Footer (4-col), PublicLayout, AppLayout, UserDropdown
- Rewrite Index.tsx as full sales funnel: Hero → Stats → Orange band → How it works → Pricing (API) → FAQ → Final CTA
- Rewrite Dashboard.tsx with real API data: credits balance, MTD spend, personas count, focus groups count, active tasks, recent transactions
- Rewrite auth pages (Login, Register, VerifyEmail, NotFound, Billing) with two-column orange-panel layout
- Replace hardcoded mock numbers in Dashboard with billingApi / personasApi / focusGroupsApi / usageApi calls
- Delete legacy components: Navigation.tsx, Hero.tsx, FeatureCard.tsx
- Add nested layout routing in App.tsx: PublicLayout for guests, AppLayout for protected routes
- Color sweep inner pages: replace all purple-500/600 with primary token
- Purge all semblance / Oliver / optical-dev references; rename semblance_app_documentation.md → cohorta_app_documentation.md; update backend scripts to cohorta_db

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 19:44:02 +01:00
Vadym Samoilenko
e01569c412 feat: commit all app changes — billing API, new auth, design overhaul
All checks were successful
Deploy to Production / deploy (push) Successful in 2m23s
Includes frontend redesign (Navigation, billingApi), backend updates
(auth routes, admin routes, LLM service refactor), MSAL removal,
and dependency updates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 19:04:43 +01:00
Vadym Samoilenko
d0ad8e67be Fix backfill: use accumulated conversation context for prompt estimation
Old logic used output text length as a proxy for prompt tokens — completely
wrong. Real Gemini calls send the full conversation history as context, so
prompt grows with every turn.

New logic:
- completion_tokens = len(response_text) / 3.8 (what was generated)
- prompt_tokens = base_template + sum(all_prior_messages_in_fg) / 3.8
  - persona_response base: 1500 tok (template + persona details + topic)
  - moderator base: 1200 tok (moderator template + fg context)
  - persona_generate base: 2500 tok (persona-detailed-generation.md template)

Also:
- Sorts messages chronologically per focus group before processing
- Accumulates context correctly so turn N includes turns 0..N-1 as context
- Idempotency via pre-fetched set instead of per-doc find_one queries
- cost_usd breakdown now has correct input/output split (not 40/60 guess)
- Dry-run prints per-focus-group cost estimates for sanity checking

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 19:11:01 +01:00
Vadym Samoilenko
d7ee22e557 Fix backfill pricing: read from model_pricing collection + --delete-existing-estimates flag 2026-04-24 18:57:25 +01:00
Vadym Samoilenko
66c8e1762e Fix backfill: handle list-type persona fields 2026-04-24 18:53:41 +01:00
Vadym Samoilenko
539c5eaaee Fix backfill script: use focus_group_messages collection + correct field names 2026-04-24 18:49:59 +01:00
Vadym Samoilenko
915c81b8f1 Complete phases D–G: quota enforcement, token invalidation, admin writes, backfill
Backend:
- token_version in JWT (bump_token_version, get_token_version on User model);
  jwt_required checks tv claim → 401 on mismatch; login routes embed version
- Quota pre-flight in all 3 LLM public methods (QuotaExceededError bubbles up)
- AI runner catches QuotaExceededError → sets status paused_quota + emits WS event
- Admin routes: POST /users (create), POST /users/<id>/reset-password,
  POST /pricing, GET /focus-groups with aggregated cost; PUT /users/<id>
  now bumps token_version on disable or role change
- backfill_usage.py: idempotent estimated-event generator for historical data,
  tiktoken for GPT models, char/3.8 for Gemini, --dry-run flag

Frontend:
- 402 interceptor dispatches quota_exceeded CustomEvent
- adminApi: createUser, resetPassword, createPricing, listFocusGroups
- UsersTab: New User dialog + Reset Password in edit dialog
- PricingTab: New Price dialog (model, provider, input/output/cached prices)
- FocusGroupsTab: focus groups table sorted by total cost
- Admin.tsx: 4th tab (Focus Groups)
- FocusGroupSession: admin-only cost badge + dismissable quota exceeded banner

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 18:34:48 +01:00
Vadym Samoilenko
3e9ccafad2 Add LLM usage tracking infrastructure (Phases A-C)
- Model renames: gpt-5.2 → gpt-5.4-2026-03-05, gemini-3-pro-preview → gemini-3.1-pro-preview; retire gpt-4.1 via alias fallback
- New: llm_usage_context.py (ContextVar-based attribution), model_pricing.py (tiered pricing + 60s cache), usage_event.py (append-only telemetry), quota.py (user/FG quota enforcement with 80% warning)
- Wire _record_usage into all 3 LLM methods; set_llm_context at every service entry point
- Fix admin_required decorator (was sync, never awaited User.find_by_id); add active_required and with_user_context decorators
- Inject user_id into ContextVar from JWT on every authenticated request
- Add DB indexes for usage_events, model_pricing, users collections
- Seed script for model pricing (gpt-5.4 single-tier, gemini-3.1 two-tier 200k threshold)
- Fix parse_json_response NameError (logger undefined at module level)
- 70 passing tests: conftest.py with sys.modules stubs, test_usage_infrastructure.py (52 tests), rewrite stale test_llm_service.py (18 tests)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 18:08:27 +01:00
Vadym Samoilenko
7f0df54de3 Fix domain typo: oliver.solution → oliver.solutions across all files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 13:40:00 +00:00
Vadym Samoilenko
bb4dca0fe8 Update production URL to optical-dev.oliver.solution
Replace ai-sandbox.oliver.solutions with optical-dev.oliver.solution
across all config, env, docs, and source files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 12:55:45 +00:00
Vadym Samoilenko
3e1865edbd Apply Jintech security audit remediation (sprint 3) — 87/92 findings fixed
- Fix missing await on FocusGroup.get_messages() (N-L1)
- Replace time.sleep with asyncio.sleep in key_theme_service and focus_group_service (N-P10)
- Replace flask import with quart in focus_groups.py (N-S3)
- Add logger.error before all 500 returns in focus_groups.py (N-P6)
- Add logging to silent except blocks across routes (N-M10, N-M11)
- Add @rate_limit to 6 remaining AI endpoints (N-H4)
- Add --confirm flag to populate scripts before delete_many (S-H2)
- Remove hardcoded Azure ID fallbacks from msal_service.py and msalConfig.ts (A-M2, F-H4)
- Centralize make_serializable() in utils.py, remove duplicates from 3 route files (N-P7)
- Replace all datetime.utcnow() with datetime.now(timezone.utc) across entire backend (M-L2)
- AuthContext.tsx: only mark token validated on 200 success, not on non-401 errors (F-H2)
- Rename authType → auth_type in auth.py (N-S4)
- Add security_report.md and security_report.pdf with full 92-finding status

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 12:51:18 +00:00
michael
c7ff1755ee Add architecture document generator and PDF
Create comprehensive technical architecture document (PDF) with 11
chapters covering system architecture, frontend/backend design, data
model, auth, WebSocket communication, LLM integration, and core
feature flows. Includes 11 Mermaid diagrams rendered as PNGs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 11:39:50 -06:00
Michael Clervi
893b537b67 changed permissions 2025-12-19 19:26:16 +00:00
michael
da7b2c0448 initial commit 2025-08-04 09:07:59 -05:00