Tasks required before the project is fully operational, grouped by priority.
This is a full-stack Nuxt app. The three server routes exist but their business logic is currently stubbed out (domain/email checks fail open; checkout proxies to a PLATFORM_API_URL that doesn't exist yet). Each needs real implementation:
- Format validation is done. The
isDomainTaken()helper currently callsPLATFORM_API_URL— replace with a direct DB query. - Add a DB client (e.g. Prisma, Drizzle) and query the sites table:
WHERE domain = fullDomain.
- The
isEmailRegistered()helper currently callsPLATFORM_API_URL— replace with a direct DB query. - Query the users table:
WHERE email = email.
- Currently proxies to
PLATFORM_API_URL. Replace with direct implementation:- Create user — hash password (e.g.
argon2.hash(password)), insert into users table. - Create site — insert into sites table with
domain,language,theme,focus. - Stripe — if
selectedPlanis PRO or PREMIUM, create a Stripe checkout session (stripe.checkout.sessions.create) and return{ url: session.url }. For free plan, generate a login token and return{ url: '/dashboard' }. - Remove
signLandingRequest()and thePLATFORM_API_URLproxy once this is self-contained.
- Create user — hash password (e.g.
bun add prisma @prisma/client argon2 stripe
Set these on Vercel (and locally in .env):
AUTH_SECRET= # shared with platform for verifiedToken signing
PLATFORM_API_URL= # e.g. https://app.topiqu.com
RESEND_API_KEY= # from resend.com
EMAIL_FROM= # e.g. Topiqu <noreply@topiqu.com>
TURNSTILE_SECRET_KEY= # from cloudflare.com/turnstile
GTAG_ID= # Google Analytics measurement ID (G-XXXXXXXX)
Users can navigate directly to any step URL without completing earlier steps. Done — app/middleware/onboarding-guard.ts redirects to the first incomplete step.
Done — pinia-plugin-persistedstate is already installed but not wired up.app/plugins/pinia-persistedstate.client.ts + persist: { pick: ['form'] } on the onboarding store.
The entire header nav is Done — hidden md:flex. There is no hamburger menu or mobile drawer.Header.vue has a slide-in mobile overlay with the same links + CTA.
The Done — security list items and the #specs section has strings that bypass i18n.JSON/REST badge now use landing.specs.security.list.* and landing.specs.api.type keys.
Generated from public/app-logo.png (1024×1024) using sips: icon-192x192.png, icon-512x512.png, apple-touch-icon.png are now in public/. Manifest and head link already configured in nuxt.config.ts.
Done — defineOgImage() was never called on any page.index.vue, tos.vue, and privacy.vue now call defineOgImage(). nuxt-og-image generates them dynamically at request time using the page title/description from useSeoMeta.
No Done — onboarding layout sets useSeoMeta() call on any onboarding step page.robots: noindex, nofollow. index.vue, tos.vue, and privacy.vue each call useSeoMeta.
Done — nuxt-gtag module is loaded but no measurement ID is set.gtag.id reads from process.env.GTAG_ID. Set GTAG_ID=G-XXXXXXXX in .env to activate.
Done — both now use nuxt.config.ts sets site.defaultLocale: 'cs' but i18n.defaultLocale is 'en'.'en'.
ads.txt contains a hardcoded publisher ID (pub-9286243311790870). Verify this is the correct account or update it.
Add and verify a sending domain in the Resend dashboard so verification emails land in inboxes rather than spam. Update EMAIL_FROM to use that domain.
When a user chooses a custom domain in the onboarding, there is no post-signup flow to guide them through adding DNS records. This was in the original platform. Needs a dashboard screen on the platform side.
The landing authenticated itself to the platform with a plain Done — replaced with short-lived HMAC: X-Landing-Secret header.X-Landing-Timestamp + X-Landing-Sig generated by server/utils/landingAuth.ts. The platform must verify: HMAC-SHA256(authSecret, timestamp) === sig and |Date.now() - timestamp| < 5min.
- Create Vercel project linked to this repo
- Set all env vars in the Vercel dashboard
- Configure custom domain + DNS
New keys added (common.status.operational, common.actions.openMenu, landing.specs.api.type, onboarding route slugs) need a native-speaker review pass.
The package is in Done — wired up.dependencies but nothing uses it yet.