-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.env.example
More file actions
157 lines (129 loc) · 5.75 KB
/
Copy path.env.example
File metadata and controls
157 lines (129 loc) · 5.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# Database
# Default host port is 5432. If a native postgres already occupies 5432 on your
# machine, set PG_HOST_PORT to a free port (e.g. 5433) — docker compose reads it
# for the published port, and update the port in the URLs below to match.
# PG_HOST_PORT=5433
DATABASE_URL="postgresql://name:password@localhost:5432/rasg-blog?schema=public"
# Cache (Valkey — Redis-compatible, provided by `docker compose up` locally)
# Unset = caching silently disabled, every request hits the DB.
# Default host port is 6379; set REDIS_HOST_PORT if that is already taken.
# REDIS_HOST_PORT=6380
REDIS_URL="redis://localhost:6379"
# Auth
AUTH_SECRET="your_auth_secret"
# AUTH_ORIGIN: REQUIRED in production — @sidebase/nuxt-auth computes its origin
# from this and the serverless function crashes (500) if it is missing. It pins
# the callback/CSRF URLs, so it MUST point at the host where OAuth completes.
# All social login funnels through app.topiqu.com (tenant subdomains hop there),
# so production uses:
# AUTH_ORIGIN="https://app.topiqu.com/api/auth"
# It must match a registered Google/GitHub redirect URI. Never ship localhost in prod.
AUTH_ORIGIN="http://localhost:3000/api/auth"
# Nuxt Nodemailer
NUXT_MAIL_USER="your_mail_user"
NUXT_MAIL_PASS="your_mail_pass"
# xAI — research (live search), sentiment, community insights
XAI_API_KEY="your_xai_api_key"
# Google Generative AI — article + LinkedIn copy (Gemini), article images (Nano Banana 2 Lite)
GOOGLE_GENERATIVE_AI_API_KEY="your_google_ai_api_key"
# OpenAI — translations, prompt enhancement (GPT-5.6 Luna)
OPENAI_API_KEY="your_openai_api_key"
# Google Auth
AUTH_GOOGLE_ID=
AUTH_GOOGLE_SECRET=
# GitHub Auth
AUTH_GITHUB_ID=
AUTH_GITHUB_SECRET=
# GIPHY API
GIPHY_API_KEY=
# CRON key
CRON_SECRET=
# Stripe API Keys
# NOTE: the Customer Portal (settings billing tab → "Manage subscription & invoices")
# requires the Portal to be enabled/configured in the Stripe Dashboard for BOTH
# test and live mode (allowed products/prices for plan switch, cancel policy,
# invoice history ON). Without it, billingPortal.sessions.create throws.
STRIPE_PK=
STRIPE_SK=
STRIPE_WEBHOOK_SECRET=
STRIPE_PRICE_PRO=price_1Tt7CtRaX8092tXvQEWn5Wcn
STRIPE_PRICE_PRO_ANNUAL=price_1Tt7CuRaX8092tXvvh4NnTXN
STRIPE_PRICE_PREMIUM=price_1TxmzARaX8092tXvaUMNV8E8
STRIPE_PRICE_PREMIUM_ANNUAL=price_1TxmzDRaX8092tXvxWDlWJ8V
# Internal Credit System
TOKEN_RATIO=1
# AWS Credentials
NUXT_AWS_ACCESS_KEY_ID=access_key_here
NUXT_AWS_SECRET_ACCESS_KEY=secret_key_here
# AWS S3 Configuration
NUXT_AWS_S3_BUCKET_NAME=topiqu-storage-eu-frankfurt
NUXT_AWS_REGION=eu-central-1
# CDN Configuration
NUXT_CDN_URL=https://cdn.topiqu.com
# Wikimedia Commons and Openverse need no key. Both are called with a User-Agent built from
# BASE_DOMAIN — Wikimedia rejects generic agents.
# LinkedIn OAuth (personal account)
APP_URL="http://localhost:3000"
LINKEDIN_CLIENT_ID_PERSONAL=
LINKEDIN_CLIENT_SECRET_PERSONAL=
# Version header for the LinkedIn REST API (YYYYMM). Update as LinkedIn sunsets versions.
LINKEDIN_API_VERSION=202604
# LinkedIn OAuth (company pages) — dormant: connecting a Page is disabled until Community
# Management API access is granted. Only token.ts still reads these, to refresh legacy rows.
LINKEDIN_CLIENT_ID_COMPANY=
LINKEDIN_CLIENT_SECRET_COMPANY=
# Google Search Console (PREMIUM content intelligence)
# Client credentials may be omitted to reuse AUTH_GOOGLE_ID / AUTH_GOOGLE_SECRET.
# Whichever client is used must have <AUTH_ORIGIN minus /api/auth>/api/search-console/callback
# registered as an authorized redirect URI, or Google answers redirect_uri_mismatch.
GOOGLE_SEARCH_CONSOLE_CLIENT_ID=
GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET=
# 32 random bytes encoded as base64. Keep stable or stored refresh tokens become unreadable.
GOOGLE_SEARCH_CONSOLE_ENCRYPTION_KEY=
# OG Image Generation
NUXT_OG_IMAGE_SECRET=
# Turnstile
TURNSTILE_SECRET_KEY=
TURNSTILE_SITE_KEY=0x4AAAAAADTMd0bwWSANE2RG
# App environment (hosting-agnostic; set on non-Vercel hosts, e.g. APP_ENV=production)
APP_ENV=
# Audit log tamper-evidence — HMAC secret (never rotate without re-anchoring the chain).
# Falls back to AUTH_SECRET when unset.
LOG_HMAC_SECRET=
# Sentry
NUXT_PUBLIC_SENTRY_DSN=
SENTRY_URL=
SENTRY_ORG=
SENTRY_PROJECT=
SENTRY_AUTH_TOKEN=
# Better Stack — Logs (HTTP / Node.js source)
BETTERSTACK_SOURCE_TOKEN=
BETTERSTACK_INGEST_HOST=
# Custom domains — clients point CNAME/ALIAS here; verification compares the DNS answer exactly.
DOMAIN_ROUTING_TARGET=domains.topiqu.com
# Better Stack — Heartbeats (one URL per scheduled task)
BETTERSTACK_HEARTBEAT_PUBLISH_CHECK=
BETTERSTACK_HEARTBEAT_GENERATE_ARTICLE=
BETTERSTACK_HEARTBEAT_SENTIMENT_ANALYSIS=
BETTERSTACK_HEARTBEAT_COMMUNITY_INSIGHTS=
BETTERSTACK_HEARTBEAT_TRANSLATE_PENDING=
BETTERSTACK_HEARTBEAT_GAM_SYNC=
BETTERSTACK_HEARTBEAT_DOMAIN_REVERIFICATION=
# Google Ad Manager — ad revenue ingest (server-side, `gam-sync` cron)
# Both of the first two must be set or the cron no-ops (see server/utils/ads/gamReport.ts).
# GAM_SERVICE_ACCOUNT_KEY: the service-account JSON key, either raw JSON on one line
# (escape newlines in private_key as \n) or the whole file base64-encoded. The service
# account needs the "Ad Manager API" enabled and a GAM user role with report access.
GAM_NETWORK_CODE=
GAM_SERVICE_ACCOUNT_KEY=
# GAM_CLIENT_DIMENSION: the report dimension that carries our `client_id` key-value
# targeting (set client-side in app/composables/useGam.ts). It is network-specific —
# look up the custom targeting key's numeric ID in GAM and use e.g.
# CUSTOM_DIMENSION_<KEY_ID>_VALUE. Missing it makes the cron fail loudly rather than
# silently attributing revenue to nobody.
GAM_CLIENT_DIMENSION=
# Optional overrides (defaults shown)
# GAM_REVENUE_METRIC=AD_EXCHANGE_REVENUE
# GAM_REPORT_TIMEZONE=UTC
# GAM_CURRENCY=USD
# GAM_REPORT_POLL_TIMEOUT_MS=300000