costhawk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +32 -0
- package/STRATEGIC_PLAN_2025-12-01.md +934 -0
- package/costcanary/.claude/settings.local.json +9 -0
- package/costcanary/.env.production.template +38 -0
- package/costcanary/.eslintrc.json +22 -0
- package/costcanary/.nvmrc +1 -0
- package/costcanary/.prettierignore +11 -0
- package/costcanary/.prettierrc.json +12 -0
- package/costcanary/ADMIN_SETUP.md +68 -0
- package/costcanary/CLAUDE.md +228 -0
- package/costcanary/CLERK_SETUP.md +69 -0
- package/costcanary/DATABASE_SETUP.md +136 -0
- package/costcanary/DEMO_CHECKLIST.md +62 -0
- package/costcanary/DEPLOYMENT.md +31 -0
- package/costcanary/PRODUCTION_RECOVERY.md +109 -0
- package/costcanary/README.md +247 -0
- package/costcanary/STRIPE_SECURITY_AUDIT.md +123 -0
- package/costcanary/TESTING_ADMIN.md +92 -0
- package/costcanary/app/(auth)/sign-in/[[...sign-in]]/page.tsx +25 -0
- package/costcanary/app/(auth)/sign-up/[[...sign-up]]/page.tsx +25 -0
- package/costcanary/app/(dashboard)/dashboard/admin/page.tsx +260 -0
- package/costcanary/app/(dashboard)/dashboard/alerts/page.tsx +64 -0
- package/costcanary/app/(dashboard)/dashboard/api-keys/page.tsx +231 -0
- package/costcanary/app/(dashboard)/dashboard/billing/page.tsx +349 -0
- package/costcanary/app/(dashboard)/dashboard/layout.tsx +188 -0
- package/costcanary/app/(dashboard)/dashboard/page.tsx +13 -0
- package/costcanary/app/(dashboard)/dashboard/playground/page.tsx +605 -0
- package/costcanary/app/(dashboard)/dashboard/settings/page.tsx +86 -0
- package/costcanary/app/(dashboard)/dashboard/usage/page.tsx +354 -0
- package/costcanary/app/(dashboard)/dashboard/wrapped-keys/page.tsx +677 -0
- package/costcanary/app/(marketing)/page.tsx +90 -0
- package/costcanary/app/(marketing)/pricing/page.tsx +272 -0
- package/costcanary/app/admin/pricing-status/page.tsx +338 -0
- package/costcanary/app/api/admin/check-pricing/route.ts +127 -0
- package/costcanary/app/api/admin/debug/route.ts +44 -0
- package/costcanary/app/api/admin/fix-pricing/route.ts +216 -0
- package/costcanary/app/api/admin/pricing-jobs/[jobId]/route.ts +48 -0
- package/costcanary/app/api/admin/pricing-jobs/route.ts +45 -0
- package/costcanary/app/api/admin/trigger-pricing/route.ts +209 -0
- package/costcanary/app/api/admin/whoami/route.ts +44 -0
- package/costcanary/app/api/auth/clerk/[...nextjs]/route.ts +93 -0
- package/costcanary/app/api/debug/wrapped-key/route.ts +51 -0
- package/costcanary/app/api/debug-status/route.ts +9 -0
- package/costcanary/app/api/debug-version/route.ts +12 -0
- package/costcanary/app/api/health/route.ts +14 -0
- package/costcanary/app/api/health-simple/route.ts +18 -0
- package/costcanary/app/api/keys/route.ts +162 -0
- package/costcanary/app/api/keys/wrapped/[id]/revoke/route.ts +86 -0
- package/costcanary/app/api/keys/wrapped/[id]/rotate/route.ts +81 -0
- package/costcanary/app/api/keys/wrapped/route.ts +241 -0
- package/costcanary/app/api/optimizer/preview/route.ts +147 -0
- package/costcanary/app/api/optimizer/route.ts +118 -0
- package/costcanary/app/api/pricing/models/route.ts +102 -0
- package/costcanary/app/api/proxy/[...path]/route.ts +391 -0
- package/costcanary/app/api/proxy/anthropic/route.ts +539 -0
- package/costcanary/app/api/proxy/google/route.ts +395 -0
- package/costcanary/app/api/proxy/openai/route.ts +529 -0
- package/costcanary/app/api/simple-test/route.ts +7 -0
- package/costcanary/app/api/stripe/checkout/route.ts +201 -0
- package/costcanary/app/api/stripe/webhook/route.ts +392 -0
- package/costcanary/app/api/test-connection/route.ts +209 -0
- package/costcanary/app/api/test-proxy/route.ts +7 -0
- package/costcanary/app/api/test-simple/route.ts +20 -0
- package/costcanary/app/api/usage/current/route.ts +112 -0
- package/costcanary/app/api/usage/stats/route.ts +129 -0
- package/costcanary/app/api/usage/stream/route.ts +113 -0
- package/costcanary/app/api/usage/summary/route.ts +67 -0
- package/costcanary/app/api/usage/trend/route.ts +119 -0
- package/costcanary/app/api/ws/route.ts +23 -0
- package/costcanary/app/globals.css +280 -0
- package/costcanary/app/layout.tsx +87 -0
- package/costcanary/components/Header.tsx +85 -0
- package/costcanary/components/dashboard/AddApiKeyModal.tsx +264 -0
- package/costcanary/components/dashboard/dashboard-content.tsx +329 -0
- package/costcanary/components/landing/DashboardPreview.tsx +222 -0
- package/costcanary/components/landing/Features.tsx +238 -0
- package/costcanary/components/landing/Footer.tsx +83 -0
- package/costcanary/components/landing/Hero.tsx +193 -0
- package/costcanary/components/landing/Pricing.tsx +250 -0
- package/costcanary/components/landing/Testimonials.tsx +248 -0
- package/costcanary/components/theme-provider.tsx +8 -0
- package/costcanary/components/ui/alert.tsx +59 -0
- package/costcanary/components/ui/badge.tsx +36 -0
- package/costcanary/components/ui/button.tsx +56 -0
- package/costcanary/components/ui/card.tsx +79 -0
- package/costcanary/components/ui/dialog.tsx +122 -0
- package/costcanary/components/ui/input.tsx +22 -0
- package/costcanary/components/ui/label.tsx +26 -0
- package/costcanary/components/ui/progress.tsx +28 -0
- package/costcanary/components/ui/select.tsx +160 -0
- package/costcanary/components/ui/separator.tsx +31 -0
- package/costcanary/components/ui/switch.tsx +29 -0
- package/costcanary/components/ui/tabs.tsx +55 -0
- package/costcanary/components/ui/toast.tsx +127 -0
- package/costcanary/components/ui/toaster.tsx +35 -0
- package/costcanary/components/ui/use-toast.ts +189 -0
- package/costcanary/components.json +17 -0
- package/costcanary/debug-wrapped-keys.md +117 -0
- package/costcanary/fix-console.sh +30 -0
- package/costcanary/lib/admin-auth.ts +226 -0
- package/costcanary/lib/admin-security.ts +124 -0
- package/costcanary/lib/audit-events.ts +62 -0
- package/costcanary/lib/audit.ts +158 -0
- package/costcanary/lib/chart-colors.ts +152 -0
- package/costcanary/lib/cost-calculator.ts +212 -0
- package/costcanary/lib/db-utils.ts +325 -0
- package/costcanary/lib/db.ts +14 -0
- package/costcanary/lib/encryption.ts +120 -0
- package/costcanary/lib/kms.ts +358 -0
- package/costcanary/lib/model-alias.ts +180 -0
- package/costcanary/lib/pricing.ts +292 -0
- package/costcanary/lib/prisma.ts +52 -0
- package/costcanary/lib/railway-db.ts +157 -0
- package/costcanary/lib/sse-parser.ts +283 -0
- package/costcanary/lib/stripe-client.ts +81 -0
- package/costcanary/lib/stripe-server.ts +52 -0
- package/costcanary/lib/tokens.ts +396 -0
- package/costcanary/lib/usage-limits.ts +164 -0
- package/costcanary/lib/utils.ts +6 -0
- package/costcanary/lib/websocket.ts +153 -0
- package/costcanary/lib/wrapped-keys.ts +531 -0
- package/costcanary/market-research.md +443 -0
- package/costcanary/middleware.ts +48 -0
- package/costcanary/next.config.js +43 -0
- package/costcanary/nia-sources.md +151 -0
- package/costcanary/package-lock.json +12162 -0
- package/costcanary/package.json +92 -0
- package/costcanary/package.json.backup +89 -0
- package/costcanary/postcss.config.js +6 -0
- package/costcanary/pricing-worker/.env.example +8 -0
- package/costcanary/pricing-worker/README.md +81 -0
- package/costcanary/pricing-worker/package-lock.json +1109 -0
- package/costcanary/pricing-worker/package.json +26 -0
- package/costcanary/pricing-worker/railway.json +13 -0
- package/costcanary/pricing-worker/schema.prisma +326 -0
- package/costcanary/pricing-worker/src/index.ts +115 -0
- package/costcanary/pricing-worker/src/services/pricing-updater.ts +79 -0
- package/costcanary/pricing-worker/src/services/tavily-client.ts +474 -0
- package/costcanary/pricing-worker/test-tavily.ts +47 -0
- package/costcanary/pricing-worker/tsconfig.json +24 -0
- package/costcanary/prisma/migrations/001_add_stripe_fields.sql +26 -0
- package/costcanary/prisma/schema.prisma +326 -0
- package/costcanary/prisma/seed-pricing.ts +133 -0
- package/costcanary/public/costhawk-logo.png +0 -0
- package/costcanary/railway.json +30 -0
- package/costcanary/railway.toml +16 -0
- package/costcanary/research-nia.md +298 -0
- package/costcanary/research.md +411 -0
- package/costcanary/scripts/build-production.js +65 -0
- package/costcanary/scripts/check-current-pricing.ts +51 -0
- package/costcanary/scripts/check-pricing-data.ts +174 -0
- package/costcanary/scripts/create-stripe-prices.js +49 -0
- package/costcanary/scripts/fix-pricing-data.ts +135 -0
- package/costcanary/scripts/fix-pricing-db.ts +148 -0
- package/costcanary/scripts/postinstall.js +58 -0
- package/costcanary/scripts/railway-deploy.sh +52 -0
- package/costcanary/scripts/run-migration.js +61 -0
- package/costcanary/scripts/start-production.js +175 -0
- package/costcanary/scripts/test-wrapped-key.ts +85 -0
- package/costcanary/scripts/validate-deployment.js +176 -0
- package/costcanary/scripts/validate-production.js +119 -0
- package/costcanary/server.js.backup +38 -0
- package/costcanary/tailwind.config.ts +216 -0
- package/costcanary/test-pricing-status.sh +27 -0
- package/costcanary/tsconfig.json +42 -0
- package/docs/sessions/session-2025-12-01.md +570 -0
- package/executive-summary.md +302 -0
- package/index.js +1 -0
- package/nia-sources.md +163 -0
- package/package.json +16 -0
- package/research.md +750 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# PRODUCTION ENVIRONMENT VARIABLES
|
|
2
|
+
# Copy to Railway environment variables dashboard
|
|
3
|
+
|
|
4
|
+
# Clerk Authentication (PRODUCTION KEYS REQUIRED)
|
|
5
|
+
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_YOUR_LIVE_PUBLISHABLE_KEY
|
|
6
|
+
CLERK_SECRET_KEY=sk_live_YOUR_LIVE_SECRET_KEY
|
|
7
|
+
|
|
8
|
+
# Clerk URLs
|
|
9
|
+
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
|
|
10
|
+
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
|
|
11
|
+
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
|
|
12
|
+
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/dashboard
|
|
13
|
+
|
|
14
|
+
# Databases (Railway auto-injected - BOTH URLs REQUIRED)
|
|
15
|
+
# Internal URL (fast but may have DNS timing issues during startup)
|
|
16
|
+
DATABASE_URL=${{Postgres.DATABASE_URL}}
|
|
17
|
+
# Public URL (reliable fallback for health checks and startup)
|
|
18
|
+
DATABASE_PUBLIC_URL=${{Postgres.DATABASE_PUBLIC_URL}}
|
|
19
|
+
REDIS_URL=${{Redis.REDIS_URL}}
|
|
20
|
+
REDIS_PUBLIC_URL=${{Redis.REDIS_PUBLIC_URL}}
|
|
21
|
+
|
|
22
|
+
# Security (CRITICAL - use production key)
|
|
23
|
+
ENCRYPTION_KEY=GENERATE_NEW_32_BYTE_HEX_KEY_FOR_PRODUCTION
|
|
24
|
+
|
|
25
|
+
# Application
|
|
26
|
+
NEXT_PUBLIC_APP_URL=https://your-app.railway.app
|
|
27
|
+
NODE_ENV=production
|
|
28
|
+
|
|
29
|
+
# Stripe (PRODUCTION KEYS)
|
|
30
|
+
STRIPE_SECRET_KEY=sk_live_YOUR_LIVE_STRIPE_SECRET_KEY
|
|
31
|
+
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_YOUR_LIVE_STRIPE_PUBLISHABLE_KEY
|
|
32
|
+
STRIPE_WEBHOOK_SECRET=whsec_YOUR_LIVE_WEBHOOK_SECRET
|
|
33
|
+
STRIPE_PRO_PRICE_ID=price_YOUR_LIVE_PRO_PRICE_ID
|
|
34
|
+
STRIPE_TEAM_PRICE_ID=price_YOUR_LIVE_TEAM_PRICE_ID
|
|
35
|
+
|
|
36
|
+
# Email (Resend)
|
|
37
|
+
RESEND_API_KEY=re_YOUR_RESEND_API_KEY
|
|
38
|
+
EMAIL_FROM=noreply@costcanary.com
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": [
|
|
3
|
+
"next/core-web-vitals",
|
|
4
|
+
"prettier"
|
|
5
|
+
],
|
|
6
|
+
"parser": "@typescript-eslint/parser",
|
|
7
|
+
"plugins": ["@typescript-eslint"],
|
|
8
|
+
"root": true,
|
|
9
|
+
"rules": {
|
|
10
|
+
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
|
|
11
|
+
"@typescript-eslint/no-explicit-any": "error",
|
|
12
|
+
"@typescript-eslint/explicit-function-return-type": "off",
|
|
13
|
+
"@typescript-eslint/explicit-module-boundary-types": "off",
|
|
14
|
+
"@typescript-eslint/no-non-null-assertion": "error",
|
|
15
|
+
"no-console": ["warn", { "allow": ["warn", "error"] }],
|
|
16
|
+
"prefer-const": "error",
|
|
17
|
+
"react/prop-types": "off",
|
|
18
|
+
"react/react-in-jsx-scope": "off",
|
|
19
|
+
"react-hooks/rules-of-hooks": "error",
|
|
20
|
+
"react-hooks/exhaustive-deps": "warn"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
20
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Admin Setup Guide
|
|
2
|
+
|
|
3
|
+
## Quick Start (For Testing Pricing Discovery)
|
|
4
|
+
|
|
5
|
+
### 1. Create Admin Organization in Clerk
|
|
6
|
+
|
|
7
|
+
1. Go to your Clerk Dashboard
|
|
8
|
+
2. Click **Organizations** in the sidebar
|
|
9
|
+
3. Click **Create Organization**
|
|
10
|
+
4. Name: "Cost Canary Admins"
|
|
11
|
+
5. Copy the **Organization ID**
|
|
12
|
+
|
|
13
|
+
### 2. Add Yourself as Admin
|
|
14
|
+
|
|
15
|
+
1. In the organization you just created
|
|
16
|
+
2. Click **Members**
|
|
17
|
+
3. Click **Invite Member**
|
|
18
|
+
4. Enter your email and set role to **admin**
|
|
19
|
+
|
|
20
|
+
### 3. Set Environment Variable in Railway
|
|
21
|
+
|
|
22
|
+
Add this to your Railway environment variables:
|
|
23
|
+
```
|
|
24
|
+
CLERK_ADMIN_ORGANIZATION_ID=org_xxxxxxxxxxxxxx
|
|
25
|
+
```
|
|
26
|
+
(Replace with your actual organization ID from step 1)
|
|
27
|
+
|
|
28
|
+
### 4. Test Admin Access
|
|
29
|
+
|
|
30
|
+
Once deployed, test your admin access:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Check if you're an admin
|
|
34
|
+
curl https://your-app.railway.app/api/admin/trigger-pricing
|
|
35
|
+
|
|
36
|
+
# Trigger test pricing discovery
|
|
37
|
+
curl -X POST https://your-app.railway.app/api/admin/trigger-pricing \
|
|
38
|
+
-H "Content-Type: application/json" \
|
|
39
|
+
-d '{"testMode": true, "provider": "OpenAI"}'
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 5. View Results
|
|
43
|
+
|
|
44
|
+
Check the job results:
|
|
45
|
+
```bash
|
|
46
|
+
curl https://your-app.railway.app/api/admin/pricing-jobs
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Admin Roles
|
|
50
|
+
|
|
51
|
+
- **super_admin**: Can do everything
|
|
52
|
+
- **admin**: Can trigger pricing discovery and view logs
|
|
53
|
+
- **viewer**: Can only view admin logs
|
|
54
|
+
|
|
55
|
+
## Security Features
|
|
56
|
+
|
|
57
|
+
โ
**Organization-based auth** - No hardcoded user IDs
|
|
58
|
+
โ
**Role-based permissions** - Different access levels
|
|
59
|
+
โ
**Rate limiting** - Max 5 triggers per hour per admin
|
|
60
|
+
โ
**Audit logging** - All admin actions logged
|
|
61
|
+
โ
**Production-ready** - Secure by default
|
|
62
|
+
|
|
63
|
+
## For Production
|
|
64
|
+
|
|
65
|
+
1. Change roles in Clerk organization to be more restrictive
|
|
66
|
+
2. Monitor audit logs in your database
|
|
67
|
+
3. Set up alerts for admin actions
|
|
68
|
+
4. Consider IP allowlisting for additional security
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
You are a Senior Principal Full-Stack Engineer with 30 years of experience across startups and FAANG companies. You think systematically, write clean code, and prioritize security above all else.
|
|
2
|
+
|
|
3
|
+
## Core Principles
|
|
4
|
+
|
|
5
|
+
### 1. SECURITY FIRST
|
|
6
|
+
- NEVER commit credentials, API keys, or secrets to GitHub
|
|
7
|
+
- ALWAYS use environment variables for sensitive data
|
|
8
|
+
- CHECK every file before committing: "Could this expose something sensitive?"
|
|
9
|
+
- Use .env.local for local development, never .env
|
|
10
|
+
- Add .env* to .gitignore IMMEDIATELY upon project creation
|
|
11
|
+
- If you accidentally expose a credential, revoke it immediately and generate a new one
|
|
12
|
+
|
|
13
|
+
### 2. DEVELOPMENT WORKFLOW
|
|
14
|
+
- NIA (Needs Immediate Attention): Security vulnerabilities, broken builds, data loss risks
|
|
15
|
+
- MCP (Mission Critical Priority): Authentication, payment processing, data integrity
|
|
16
|
+
- NEVER push directly to main branch - always use feature branches
|
|
17
|
+
- Commit messages: Keep them simple and professional. Format: "feat:", "fix:", "docs:", "style:", "refactor:"
|
|
18
|
+
- NEVER mention Claude, AI, or code generation tools
|
|
19
|
+
- Be concise and descriptive about WHAT changed, not HOW it was created
|
|
20
|
+
- Example: "feat: add authentication with Clerk" NOT "feat: AI-generated auth system"
|
|
21
|
+
- Test locally before pushing ANYTHING
|
|
22
|
+
- One feature = One commit (atomic commits)
|
|
23
|
+
|
|
24
|
+
### 3. CODE QUALITY
|
|
25
|
+
- Write code for humans first, computers second
|
|
26
|
+
- Every function should do ONE thing well
|
|
27
|
+
- If you need comments to explain WHAT, refactor the code
|
|
28
|
+
- Comments explain WHY, not WHAT
|
|
29
|
+
- No magic numbers - use named constants
|
|
30
|
+
- DRY (Don't Repeat Yourself) but don't over-abstract
|
|
31
|
+
|
|
32
|
+
### 4. VISUAL EXCELLENCE
|
|
33
|
+
- This is 2025 - users expect Stripe-level design quality
|
|
34
|
+
- Use Framer Motion for smooth animations
|
|
35
|
+
- Implement micro-interactions (hover states, loading states, transitions)
|
|
36
|
+
- Dark mode is mandatory, light mode is optional
|
|
37
|
+
- Accessibility is not optional - WCAG 2.1 AA minimum
|
|
38
|
+
- Performance matters - lazy load, optimize images, minimize bundle size
|
|
39
|
+
|
|
40
|
+
### 5. CRITICAL THINKING
|
|
41
|
+
- Question requirements: "Is this the real problem we're solving?"
|
|
42
|
+
- Consider edge cases: "What happens when this fails?"
|
|
43
|
+
- Think scale: "Will this work with 10x the data?"
|
|
44
|
+
- Ask yourself: "How would I attack this system?"
|
|
45
|
+
- Always have a rollback plan
|
|
46
|
+
- Monitor everything that could break
|
|
47
|
+
|
|
48
|
+
### 6. MODERN STACK DECISIONS
|
|
49
|
+
- Choose boring technology for critical paths
|
|
50
|
+
- Use managed services (Clerk, Railway, Vercel) over self-hosted
|
|
51
|
+
- Serverless first, servers when necessary
|
|
52
|
+
- TypeScript always, JavaScript never
|
|
53
|
+
- Postgres for data, Redis for cache, nothing exotic
|
|
54
|
+
|
|
55
|
+
### 7. USER EXPERIENCE
|
|
56
|
+
- Every interaction should feel instant (<100ms)
|
|
57
|
+
- Loading states are better than frozen UI
|
|
58
|
+
- Error messages should tell users what to do next
|
|
59
|
+
- Optimistic updates with rollback on failure
|
|
60
|
+
- Progressive enhancement - core features work without JavaScript
|
|
61
|
+
|
|
62
|
+
### 8. PROFESSIONAL BEHAVIOR
|
|
63
|
+
- Document your decisions in code
|
|
64
|
+
- Write README as if you'll forget everything in 6 months
|
|
65
|
+
- Set up CI/CD on day one, not day 100
|
|
66
|
+
- Monitor production like your salary depends on it
|
|
67
|
+
- Teach through code reviews, don't just critique
|
|
68
|
+
|
|
69
|
+
Remember: You're building production software that real people depend on. Act accordingly.
|
|
70
|
+
|
|
71
|
+
## PROJECT: COSTHAWK (Rebranded from Cost Canary)
|
|
72
|
+
|
|
73
|
+
### Project Overview
|
|
74
|
+
- **Project Name**: CostHawk - AI API cost monitoring and optimization platform
|
|
75
|
+
- **Brand**: CostHawk (UI displays this name, internal code still uses costcanary)
|
|
76
|
+
- **Logo**: Hawk icon with circuit patterns at `/public/costhawk-logo.png`
|
|
77
|
+
- **Purpose**: Track and optimize AI API costs across providers (OpenAI, Anthropic, etc.)
|
|
78
|
+
|
|
79
|
+
### GitHub Repository
|
|
80
|
+
- **Remote URL**: https://github.com/cdilling/costcanary.git
|
|
81
|
+
- **Branch Strategy**: Always work on feature branches, never push directly to main
|
|
82
|
+
- **Before Pushing**: ALWAYS verify no secrets are exposed with `git status` and `git diff`
|
|
83
|
+
|
|
84
|
+
### Railway Deployment
|
|
85
|
+
- **Live URL**: Deployed on Railway (check Railway dashboard for URL)
|
|
86
|
+
- **Auto-deploy**: Enabled from main branch
|
|
87
|
+
- **Build Command**: `npm run build` (use `npx prisma generate && npx prisma db push && npm run build` for first-time database setup)
|
|
88
|
+
|
|
89
|
+
### Database Architecture (Completed Aug 14, 2025)
|
|
90
|
+
- **PostgreSQL**: Hosted on Railway, all tables created and migrated
|
|
91
|
+
- **Redis**: Hosted on Railway, connected and ready for caching
|
|
92
|
+
- **Prisma ORM**: Configured with complete schema including User, ApiKey, UsageLog, Budget, Alert, AuditLog models
|
|
93
|
+
- **Security**: AES-256-CBC encryption for all API keys with unique IV per encryption
|
|
94
|
+
|
|
95
|
+
### Environment Variables (Set in Railway)
|
|
96
|
+
```
|
|
97
|
+
# Clerk Authentication (CONFIGURED)
|
|
98
|
+
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_ZXF1aXBwZWQtbW91c2UtODYuY2xlcmsuYWNjb3VudHMuZGV2JA
|
|
99
|
+
CLERK_SECRET_KEY=sk_test_dVrwYXJ79GbHiNMpDBsh2w2Lx6bDjtzeSB57E8gRY3
|
|
100
|
+
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
|
|
101
|
+
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
|
|
102
|
+
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
|
|
103
|
+
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/dashboard
|
|
104
|
+
|
|
105
|
+
# Databases (Connected via Railway)
|
|
106
|
+
DATABASE_URL=${{Postgres.DATABASE_URL}}
|
|
107
|
+
DATABASE_PUBLIC_URL=${{Postgres.DATABASE_PUBLIC_URL}}
|
|
108
|
+
REDIS_URL=${{Redis.REDIS_URL}}
|
|
109
|
+
REDIS_PUBLIC_URL=${{Redis.REDIS_PUBLIC_URL}}
|
|
110
|
+
|
|
111
|
+
# Security (CRITICAL - 32-byte hex key)
|
|
112
|
+
ENCRYPTION_KEY=a2ef4f139870d5f1a248107c8e92372513644e204e2c637a0927b4b6e93c0ec0
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Project Structure
|
|
116
|
+
```
|
|
117
|
+
costcanary/
|
|
118
|
+
โโโ app/
|
|
119
|
+
โ โโโ (auth)/ # Clerk authentication pages
|
|
120
|
+
โ โโโ (dashboard)/ # Protected dashboard routes
|
|
121
|
+
โ โโโ (marketing)/ # Public landing page with animations
|
|
122
|
+
โ โโโ api/ # API routes (proxy endpoint coming next)
|
|
123
|
+
โโโ components/
|
|
124
|
+
โ โโโ ui/ # shadcn/ui components
|
|
125
|
+
โ โโโ landing/ # Hero, Features, Pricing, Testimonials, Footer
|
|
126
|
+
โ โโโ dashboard/ # Dashboard components
|
|
127
|
+
โโโ lib/
|
|
128
|
+
โ โโโ prisma.ts # Database client singleton
|
|
129
|
+
โ โโโ encryption.ts # AES-256 encryption utilities
|
|
130
|
+
โ โโโ db-utils.ts # Database helpers (user, API keys, usage)
|
|
131
|
+
โ โโโ audit.ts # Audit logging functionality
|
|
132
|
+
โ โโโ cost-calculator.ts # Provider-specific cost calculations
|
|
133
|
+
โโโ prisma/
|
|
134
|
+
โ โโโ schema.prisma # Complete database schema
|
|
135
|
+
โโโ middleware.ts # Clerk authentication middleware
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Key Files Created
|
|
139
|
+
1. **lib/encryption.ts** - Encrypts/decrypts API keys with AES-256-CBC
|
|
140
|
+
2. **lib/prisma.ts** - Database connection singleton with proper typing
|
|
141
|
+
3. **lib/db-utils.ts** - Helper functions for user management, API key storage, usage tracking
|
|
142
|
+
4. **lib/audit.ts** - Audit logging for compliance and security
|
|
143
|
+
5. **lib/cost-calculator.ts** - Calculates costs for all providers (OpenAI, Anthropic, etc.)
|
|
144
|
+
6. **lib/admin-auth.ts** - Admin authentication and permission checking
|
|
145
|
+
7. **prisma/schema.prisma** - Complete database schema with indexes and relations
|
|
146
|
+
8. **app/api/pricing/models/route.ts** - API endpoint for fetching pricing models
|
|
147
|
+
9. **app/api/admin/fix-pricing/route.ts** - Admin endpoint to repair/update pricing data
|
|
148
|
+
|
|
149
|
+
### Known Issues & Solutions
|
|
150
|
+
1. **Prisma Json Type Error**: Changed `Record<string, unknown>` to properly typed `JsonSerializable`
|
|
151
|
+
2. **ESLint Errors**: Fixed unused variables with underscore prefix convention, removed unused imports
|
|
152
|
+
3. **TypeScript Strict Mode**: All types properly defined for production build
|
|
153
|
+
4. **Railway HPE_HEADER_OVERFLOW**: Fixed with optimized Node.js settings in package.json
|
|
154
|
+
5. **Build Warnings**: `<img>` tags work fine, Next Image optimization optional
|
|
155
|
+
|
|
156
|
+
### MCP Servers Configured
|
|
157
|
+
1. **NIA MCP Server**: Installed and configured with API key
|
|
158
|
+
2. **Context7**: For fetching documentation
|
|
159
|
+
3. **Clerk**: Authentication toolkit with publishable key
|
|
160
|
+
|
|
161
|
+
### Recent Updates (August 2025)
|
|
162
|
+
|
|
163
|
+
#### Admin System & Pricing Management
|
|
164
|
+
1. **Admin Authentication**: Organization-based admin system via Clerk
|
|
165
|
+
- Admin organization: "Cost Canary Admins"
|
|
166
|
+
- Permissions: trigger pricing discovery, view admin logs, view sensitive data
|
|
167
|
+
- Admin panel in dashboard sidebar (only visible to admins)
|
|
168
|
+
|
|
169
|
+
2. **Pricing Data System**:
|
|
170
|
+
- Database stores pricing for all AI models (GPT-5, Claude 4.1, etc.)
|
|
171
|
+
- Admin endpoints: `/api/admin/check-pricing`, `/api/admin/fix-pricing`
|
|
172
|
+
- Pricing discovery worker with Tavily integration
|
|
173
|
+
- August 2025 models added with correct pricing
|
|
174
|
+
|
|
175
|
+
3. **Playground Updates**:
|
|
176
|
+
- Dynamic model loading from database (`/api/pricing/models`)
|
|
177
|
+
- Real-time pricing display below model selection
|
|
178
|
+
- Cost calculation using actual database pricing
|
|
179
|
+
- Support for wrapped API keys testing
|
|
180
|
+
|
|
181
|
+
#### UI Rebrand to CostHawk
|
|
182
|
+
- All user-facing text updated from "Cost Canary" to "CostHawk"
|
|
183
|
+
- New hawk logo with circuit patterns
|
|
184
|
+
- Updated metadata and page titles
|
|
185
|
+
- Internal code references remain as "costcanary" for stability
|
|
186
|
+
|
|
187
|
+
### Admin Features
|
|
188
|
+
- **Pricing Status Page**: `/admin/pricing-status` - View all model pricing
|
|
189
|
+
- **Trigger Discovery**: `/api/admin/trigger-pricing` - Force pricing update
|
|
190
|
+
- **Fix Pricing**: `/api/admin/fix-pricing` - Repair/update pricing data
|
|
191
|
+
- **Admin Overview**: `/dashboard/admin` - Admin dashboard
|
|
192
|
+
|
|
193
|
+
### Next Steps
|
|
194
|
+
- Complete API Proxy implementation with cost tracking
|
|
195
|
+
- Implement real-time usage analytics dashboard
|
|
196
|
+
- Add budget alerts and notification system
|
|
197
|
+
- Integrate Stripe for billing
|
|
198
|
+
|
|
199
|
+
### Testing Commands
|
|
200
|
+
```bash
|
|
201
|
+
# Verify database connection
|
|
202
|
+
npx prisma studio
|
|
203
|
+
|
|
204
|
+
# Run locally
|
|
205
|
+
npm run dev
|
|
206
|
+
|
|
207
|
+
# Type checking
|
|
208
|
+
npx tsc --noEmit
|
|
209
|
+
|
|
210
|
+
# Linting
|
|
211
|
+
npm run lint
|
|
212
|
+
|
|
213
|
+
# Format code
|
|
214
|
+
npm run format
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Security Reminders
|
|
218
|
+
- NEVER commit .env.local
|
|
219
|
+
- ALWAYS encrypt API keys before storage
|
|
220
|
+
- Audit log all sensitive operations
|
|
221
|
+
- Use Row Level Security (enforced at application level)
|
|
222
|
+
- Regular backups handled by Railway
|
|
223
|
+
|
|
224
|
+
### Performance Notes
|
|
225
|
+
- Composite indexes on userId, timestamp, provider
|
|
226
|
+
- Connection pooling handled by Prisma
|
|
227
|
+
- Redis ready for caching when needed
|
|
228
|
+
- Lazy loading on landing page components
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Clerk Setup for Cost Canary
|
|
2
|
+
|
|
3
|
+
## Current Configuration
|
|
4
|
+
Your app is using these Clerk credentials:
|
|
5
|
+
- Instance: `equipped-mouse-86.clerk.accounts.dev`
|
|
6
|
+
- Publishable Key: `pk_test_ZXF1aXBwZWQtbW91c2UtODYuY2xlcmsuYWNjb3VudHMuZGV2JA`
|
|
7
|
+
|
|
8
|
+
## If You Can't Find Your Clerk App
|
|
9
|
+
|
|
10
|
+
### Option 1: Create a New Clerk Application
|
|
11
|
+
1. Go to https://dashboard.clerk.com
|
|
12
|
+
2. Click "Create application"
|
|
13
|
+
3. Name it "Cost Canary"
|
|
14
|
+
4. Choose "Next.js" as your framework
|
|
15
|
+
5. Get your new keys from the dashboard
|
|
16
|
+
|
|
17
|
+
### Option 2: Use Existing Test Keys (Development Only)
|
|
18
|
+
The current test keys in your environment should work for development:
|
|
19
|
+
```env
|
|
20
|
+
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_ZXF1aXBwZWQtbW91c2UtODYuY2xlcmsuYWNjb3VudHMuZGV2JA
|
|
21
|
+
CLERK_SECRET_KEY=sk_test_dVrwYXJ79GbHiNMpDBsh2w2Lx6bDjtzeSB57E8gRY3
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Option 3: Create New Production Keys
|
|
25
|
+
If you need production keys:
|
|
26
|
+
1. Create a new Clerk application
|
|
27
|
+
2. Go to API Keys section
|
|
28
|
+
3. Copy the production keys (they start with `pk_live_` and `sk_live_`)
|
|
29
|
+
4. Update in Railway environment variables
|
|
30
|
+
|
|
31
|
+
## Update Railway Environment Variables
|
|
32
|
+
|
|
33
|
+
Once you have your keys, update them in Railway:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# For new test keys
|
|
37
|
+
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_YOUR_NEW_KEY
|
|
38
|
+
CLERK_SECRET_KEY=sk_test_YOUR_NEW_SECRET
|
|
39
|
+
|
|
40
|
+
# For production keys
|
|
41
|
+
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_YOUR_PRODUCTION_KEY
|
|
42
|
+
CLERK_SECRET_KEY=sk_live_YOUR_PRODUCTION_SECRET
|
|
43
|
+
|
|
44
|
+
# Don't forget the webhook secret (if using webhooks)
|
|
45
|
+
CLERK_WEBHOOK_SECRET=whsec_YOUR_WEBHOOK_SECRET
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Testing Your Setup
|
|
49
|
+
|
|
50
|
+
1. Local testing:
|
|
51
|
+
```bash
|
|
52
|
+
npm run dev
|
|
53
|
+
# Visit http://localhost:3000
|
|
54
|
+
# Try to sign up/sign in
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
2. Check if authentication works:
|
|
58
|
+
- Click "Sign In" button
|
|
59
|
+
- Should redirect to Clerk's hosted sign-in page
|
|
60
|
+
- After sign-in, should redirect back to dashboard
|
|
61
|
+
|
|
62
|
+
## If Nothing Works
|
|
63
|
+
|
|
64
|
+
The test keys in your current setup (`equipped-mouse-86`) should still be functional unless:
|
|
65
|
+
- The Clerk application was deleted
|
|
66
|
+
- The keys were revoked
|
|
67
|
+
- You're hitting rate limits
|
|
68
|
+
|
|
69
|
+
In that case, creating a new Clerk application is the fastest solution.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Database Setup Guide
|
|
2
|
+
|
|
3
|
+
## ๐ Security First
|
|
4
|
+
|
|
5
|
+
**CRITICAL**: Never commit database credentials or encryption keys to Git.
|
|
6
|
+
|
|
7
|
+
## ๐ฆ Railway PostgreSQL Setup
|
|
8
|
+
|
|
9
|
+
1. **Create Database on Railway**:
|
|
10
|
+
- Go to your Railway project
|
|
11
|
+
- Click "New Service" โ "Database" โ "PostgreSQL"
|
|
12
|
+
- Railway will automatically provision a PostgreSQL database
|
|
13
|
+
|
|
14
|
+
2. **Get Database URL**:
|
|
15
|
+
- Click on your PostgreSQL service
|
|
16
|
+
- Go to "Variables" tab
|
|
17
|
+
- Copy the `DATABASE_URL` value
|
|
18
|
+
|
|
19
|
+
3. **Update Local Environment**:
|
|
20
|
+
```bash
|
|
21
|
+
# .env.local
|
|
22
|
+
DATABASE_URL="postgresql://postgres:xxxxx@xxxxx.railway.app:xxxx/railway"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
4. **Add to Railway Environment**:
|
|
26
|
+
- Go to your app service in Railway
|
|
27
|
+
- Click "Variables"
|
|
28
|
+
- Add:
|
|
29
|
+
- `DATABASE_URL` (from PostgreSQL service)
|
|
30
|
+
- `ENCRYPTION_KEY` (from your .env.local)
|
|
31
|
+
|
|
32
|
+
## ๐๏ธ Database Schema
|
|
33
|
+
|
|
34
|
+
Our schema includes:
|
|
35
|
+
- **User**: Synced with Clerk authentication
|
|
36
|
+
- **ApiKey**: Encrypted API keys with AES-256
|
|
37
|
+
- **UsageLog**: Detailed API usage tracking
|
|
38
|
+
- **Budget**: Spending limits and alerts
|
|
39
|
+
- **Alert**: Notifications for budget/usage
|
|
40
|
+
- **AuditLog**: Security audit trail
|
|
41
|
+
|
|
42
|
+
## ๐ Migration Commands
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Generate migration (development)
|
|
46
|
+
npx prisma migrate dev --name init
|
|
47
|
+
|
|
48
|
+
# Apply migrations (production)
|
|
49
|
+
npx prisma migrate deploy
|
|
50
|
+
|
|
51
|
+
# Generate Prisma Client
|
|
52
|
+
npx prisma generate
|
|
53
|
+
|
|
54
|
+
# Open Prisma Studio (GUI)
|
|
55
|
+
npx prisma studio
|
|
56
|
+
|
|
57
|
+
# Reset database (CAUTION: deletes all data)
|
|
58
|
+
npx prisma migrate reset
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## ๐ Security Features
|
|
62
|
+
|
|
63
|
+
1. **API Key Encryption**:
|
|
64
|
+
- All API keys encrypted with AES-256-CBC
|
|
65
|
+
- Unique IV for each encryption
|
|
66
|
+
- Keys never stored in plain text
|
|
67
|
+
|
|
68
|
+
2. **Row Level Security**:
|
|
69
|
+
- Users can only access their own data
|
|
70
|
+
- Enforced at application level via Prisma
|
|
71
|
+
|
|
72
|
+
3. **Audit Logging**:
|
|
73
|
+
- All sensitive operations logged
|
|
74
|
+
- IP address and user agent tracking
|
|
75
|
+
- GDPR-compliant retention policies
|
|
76
|
+
|
|
77
|
+
## ๐ Performance Optimizations
|
|
78
|
+
|
|
79
|
+
1. **Indexes**:
|
|
80
|
+
- Composite indexes for common queries
|
|
81
|
+
- Timestamp indexes for time-series data
|
|
82
|
+
- Provider/model indexes for filtering
|
|
83
|
+
|
|
84
|
+
2. **Connection Pooling**:
|
|
85
|
+
- Prisma handles connection pooling automatically
|
|
86
|
+
- Configurable via `DATABASE_URL` parameters
|
|
87
|
+
|
|
88
|
+
3. **Query Optimization**:
|
|
89
|
+
- Use `select` to limit returned fields
|
|
90
|
+
- Batch operations with `createMany`
|
|
91
|
+
- Aggregate queries for statistics
|
|
92
|
+
|
|
93
|
+
## ๐งช Testing Database
|
|
94
|
+
|
|
95
|
+
For local development without Railway:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Using Docker
|
|
99
|
+
docker run --name costcanary-db \
|
|
100
|
+
-e POSTGRES_PASSWORD=localpass \
|
|
101
|
+
-e POSTGRES_DB=costcanary \
|
|
102
|
+
-p 5432:5432 \
|
|
103
|
+
-d postgres:15
|
|
104
|
+
|
|
105
|
+
# Update .env.local
|
|
106
|
+
DATABASE_URL="postgresql://postgres:localpass@localhost:5432/costcanary"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## ๐ Monitoring
|
|
110
|
+
|
|
111
|
+
- Railway provides database metrics
|
|
112
|
+
- Monitor slow queries with Prisma logging
|
|
113
|
+
- Set up alerts for connection issues
|
|
114
|
+
|
|
115
|
+
## ๐ Troubleshooting
|
|
116
|
+
|
|
117
|
+
1. **Connection Refused**:
|
|
118
|
+
- Check DATABASE_URL format
|
|
119
|
+
- Ensure Railway database is running
|
|
120
|
+
- Verify network connectivity
|
|
121
|
+
|
|
122
|
+
2. **Migration Errors**:
|
|
123
|
+
- Check for pending migrations: `npx prisma migrate status`
|
|
124
|
+
- Reset if needed: `npx prisma migrate reset`
|
|
125
|
+
|
|
126
|
+
3. **Type Errors**:
|
|
127
|
+
- Regenerate client: `npx prisma generate`
|
|
128
|
+
- Restart TypeScript server in VS Code
|
|
129
|
+
|
|
130
|
+
## ๐ Best Practices
|
|
131
|
+
|
|
132
|
+
1. Always use transactions for multi-step operations
|
|
133
|
+
2. Implement retry logic for network issues
|
|
134
|
+
3. Regular backups (Railway handles this)
|
|
135
|
+
4. Monitor database size and performance
|
|
136
|
+
5. Clean up old audit logs periodically
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Demo Checklist - Cost Canary
|
|
2
|
+
|
|
3
|
+
## Pre-Demo Verification (5 minutes)
|
|
4
|
+
|
|
5
|
+
### 1. Landing Page โ
|
|
6
|
+
- [ ] Visit homepage - animations load
|
|
7
|
+
- [ ] Pricing toggle works
|
|
8
|
+
- [ ] CTA buttons redirect to sign-up
|
|
9
|
+
|
|
10
|
+
### 2. Authentication Flow โ
|
|
11
|
+
- [ ] Sign up with test email
|
|
12
|
+
- [ ] Email verification (if required)
|
|
13
|
+
- [ ] Redirects to /dashboard after signup
|
|
14
|
+
|
|
15
|
+
### 3. Dashboard Core Features โ
|
|
16
|
+
- [ ] Dashboard loads without errors
|
|
17
|
+
- [ ] API Keys page accessible
|
|
18
|
+
- [ ] Usage page shows data structure
|
|
19
|
+
- [ ] Playground page loads
|
|
20
|
+
|
|
21
|
+
### 4. Database Connection โ
|
|
22
|
+
- [ ] No Prisma connection errors in Railway logs
|
|
23
|
+
- [ ] User creation works on signup
|
|
24
|
+
- [ ] API key storage/retrieval functions
|
|
25
|
+
|
|
26
|
+
## Demo Flow (10 minutes)
|
|
27
|
+
|
|
28
|
+
### Landing โ Sign Up โ Dashboard
|
|
29
|
+
1. **Homepage** (1 min)
|
|
30
|
+
- Show hero animation
|
|
31
|
+
- Highlight pricing ($0 free tier)
|
|
32
|
+
- Demonstrate mobile responsiveness
|
|
33
|
+
|
|
34
|
+
2. **Authentication** (2 min)
|
|
35
|
+
- Sign up with demo email
|
|
36
|
+
- Show smooth redirect to dashboard
|
|
37
|
+
|
|
38
|
+
3. **Dashboard Overview** (3 min)
|
|
39
|
+
- Point out navigation structure
|
|
40
|
+
- Show API keys management
|
|
41
|
+
- Preview usage analytics
|
|
42
|
+
- Mention playground feature
|
|
43
|
+
|
|
44
|
+
4. **Key Features** (4 min)
|
|
45
|
+
- Highlight encryption security
|
|
46
|
+
- Show provider support (OpenAI, Anthropic, etc.)
|
|
47
|
+
- Point out real-time monitoring capability
|
|
48
|
+
- Demonstrate responsive design
|
|
49
|
+
|
|
50
|
+
## Emergency Fallbacks
|
|
51
|
+
|
|
52
|
+
If deployment fails:
|
|
53
|
+
- [ ] Use local development (`npm run dev`)
|
|
54
|
+
- [ ] Screen recording of working features
|
|
55
|
+
- [ ] Focus on code quality and architecture
|
|
56
|
+
|
|
57
|
+
## Railway Deployment Check
|
|
58
|
+
|
|
59
|
+
Current status: Building static pages (7/28)
|
|
60
|
+
Expected completion: 2-3 more minutes
|
|
61
|
+
|
|
62
|
+
Post-deployment URL: Check Railway dashboard
|