Skip to content

Prego Web App Standard (Draft v1.0)

This document is the canonical standard for PREGO web applications in the monorepo (apps/www, apps/admin-web, apps/client-web). It is designed for operational stability on Cloudflare, reuse across SaaS surfaces, and predictable behavior for IDE-assisted development.

Related (read together):

TopicDocument
Public API change orderHow to add an API
Browser → Zuplo vs thin BFFAPI gateway & BFF governancenot “Zuplo only” dogma; short exception list
Headers, trust zonesTenant & trust boundaries
Repo ownershipRepo responsibility matrix
Refactoring program contextWeb app standardization plan
Safe refactor audit (behavior-preserving)Web app safe refactor status
Cursor copy-paste promptsWeb app refactoring prompt (Cursor)
IDE / agentsIDE guide

1. Objective

This standard applies to all PREGO web apps (www, admin-web, client-web) to achieve:

  • Consistent development practices across the product web tier
  • Cloudflare-aligned deployment and runtime expectations
  • AI IDE (Cursor, etc.) — clear boundaries and shared contracts
  • Reusable SaaS platform — shared packages and schema-first contracts

2. Architecture principles

2.1 Layer model

[ User Interface Layer ]
→ Next.js (www / admin-web / client-web)
[ Edge API Layer ]
→ Cloudflare Workers (Hono where used for HTTP services)
[ Gateway Layer ]
→ Zuplo (auth policies, rate limits, header transforms, routing)
[ Data & platform state ]
→ D1 / R2 / KV / Vectorize (per Worker bindings and product)
[ Domain backend ]
→ Frappe (ERP)
[ Observability ]
→ Logpush / Analytics / R2 (as configured per environment)

Boundary note: ERP business rules live in Frappe; Retrieval/runtime in prego_ai; orchestration and tenant master data in prego-control-plane. Workers implement edge/API and orchestration — not a duplicate of Frappe domain logic. See the repo responsibility matrix.

2.2 Design principles

  1. Edge-first — Prefer gateway + Workers for multi-tenant and cross-app APIs.
  2. Stateless UI — Sessions and secrets follow existing app patterns; no hidden server state in UI packages.
  3. Schema-first contractsZod (and shared types) for inputs/outputs that cross app boundaries.
  4. Gateway-first public APIDefault: browser and external consumers use Zuplo as the public API surface; exceptions (thin BFF, presigned upload, Pages Functions) are documented and minimal. See API gateway & BFF governance.
  5. Workers own edge/service HTTP behaviorDo not implement Worker-equivalent business APIs inside Next routes; Next orchestrates UI and same-origin needs only.
  6. Shared package–first — Prefer packages/* over duplicated components, schemas, or clients.

2.3 Scope — in / out (web tier)

This standard applies to the three Next.js product applications in the monorepo: apps/www, apps/admin-web, apps/client-web.

Out of scope (not governed by this document; use their own repos, runbooks, or doc hubs):

  • Documentation sites built with Starlight, VitePress, Docusaurus, or similar static doc frameworks — including the monorepo internal docs tree under docs/ (Starlight) and separate product-documentation repositories (e.g. public docs mirrors). Their stack, routing, and content pipelines are not “web app standard” targets.
  • Other external documentation or CMS surfaces that are not one of the three Next apps.
  • Backend / infra / gateway authoring (Frappe, Pulumi, Ansible, prego-zuplo OpenAPI, Workers-only repos) — see the platform hub and repo responsibility matrix.

Rationale: Mixing Starlight (or any doc framework) with product Next apps in one standard creates false obligations (forms, Zuplo, Cloudflare Pages app patterns). Keep product web tier rules separate from documentation tooling.


3. Web app standard (www / admin / client)

3.1 Common technical stack

AreaStandard
FrameworkNext.jsone agreed major across the three apps (upgrade path in standardization plan)
LanguageTypeScript (strict)
UITailwind + shadcn/ui (shared tokens/patterns via packages where applicable)
FormsReact Hook Form
ValidationZodrequired for user input and shared contracts
Server/async dataTanStack Query where the app already uses it; align patterns across apps over time
Runtime / deployCloudflare — see §7 (www may remain static export + Pages; admin/client target OpenNext on Workers alignment)

3.2 Prohibited (web tier)

  • Per-app ad hoc validation — no parallel validation stacks for the same flows; use Zod (+ RHF resolvers).
  • Bypassing the gateway for public multi-consumer APIs — do not call Worker origins directly from the browser when the contract is meant to go through Zuplo (see BFF exceptions).
  • Embedding Worker-grade orchestration or domain logic in Next — keep edge/service logic in Workers (and Frappe for ERP).
  • Duplicating UI — extract to packages/ui (or existing shared packages) instead of copy-paste.

3.3 App roles

AppRoleDeploy posture (target)
wwwMarketing — SEO, landing, pricing; static-firstCloudflare Pages (static export)
admin-webHighest-contract surface — onboarding, auth handoff, billing, tenant/plan/region, provisioning entryOpenNext + Worker
client-webPrimary SaaS UI — ERP + assistant featuresCloudflare; align toward same Next-on-Workers strategy as admin-web (see plan)

3.4 Implementation status (monorepo snapshot)

This is a living snapshot of where the standard is applied in the Prego monorepo — not a completeness claim. Details: Web app safe refactor status.

SurfaceRHF + Zod (email OTP entry)Notes
@platform/web-auth-schemasauthEmailSchema, authEmailStringSchema, AUTH_EMAIL_RE, signInSchema / signUpSchema (password Hono JSON)YesShared workspace package: admin-web (/signup, AuthCard, onboarding / step 2), www (TrialEmailGate, manual approval workEmail in manual-approval-verify-schema.ts), client-web auth flows + lib/schemas/onboarding + invoices/create + lib/schemas/auth (re-exports Hono sign-in/up JSON).
admin-web — OTP verify (EmailOtpVerifyPanel)AlignedRHF + zodResolver on z.object({ code: otpCodeSchema }); six inputs sync to code via setValue; verifyOtp / resend errors use setError('root').
admin-webCompanyInfoStep (onboarding step 4)AlignedRHF + zodResolver + useFieldArray; Zod (lib/schemas/company-info-step.ts): subdomain via validateSubdomain, company length, invite emails via authEmailStringSchema.
client-webAligned (auth / email + selected ERP)package.json has Zod + RHF. SignUpPage, forgot-passcode, SignInForm, verify-email (email in useForm), invoices/create (recipientEmail) use RHF + shared Zod; verify-email CodeEntryForm submits the six-digit code via parsePasscodePinFromInput before POST /auth/otp/verify. Passcode keypad routes (passcode/set, passcode/change, reset-passcode, dedicated /passcode, SignInForm verify step → /auth/verify) use parsePasscodePin and PASSCODE_PIN_LENGTH (lib/schemas/passcode-pin, same six digits as OTP) before gateway calls — not RHF. ERP-style flows use lib/schemas/* (e.g. checklist add, leave request, expense capture validation) with RHF where applicable; expand per-screen. pnpm run verify includes Vitest test:unit (e.g. Assistant UI app/my-ai/page-controller/*.test.ts, lib/schemas/*.test.ts); see apps/client-web/AGENTS.md. Assistant UI @/app/my-ai/page-controller barrel: ESLint no-restricted-imports in eslint.config.mjs (only app/my-ai/page.tsx + app/my-ai/page-controller/**).

4. API & edge standard

4.1 Request flow (default)

Client (Next)
→ Zuplo (gateway)
→ Worker (e.g. Hono in prego_ai / patterns in control-plane)
→ D1 / R2 / KV / Vectorize (as bound)

BFF exception path (allowed when narrow): same-origin Next app/api/*, Pages Functions, or presigned flows — per API gateway & BFF governance.

4.2 Worker standard (HTTP services using Hono)

ItemRule
FrameworkHono for new HTTP routing in Workers where the repo already standardizes on it
ValidationZod at boundaries
ResponseJSON, typed
LoggingInclude request correlation (and tenant/user fields where applicable)
ErrorsStructured errors — consistent shape for clients

Existing Workers without Hono may migrate incrementally; new routes should follow repo conventions.

4.3 Zuplo responsibilities

  • Authentication and policy enforcement at the edge
  • Rate limiting
  • Header transforms (e.g. tenant context) per Tenant & trust boundaries
  • Usage / routing metadata as configured

No business rules in the gateway — policy and forwarding only.


5. Data layer (Cloudflare)

5.1 Storage roles (illustrative)

ServiceTypical use
D1Relational metadata (e.g. control-plane)
R2Files, exports, log sinks
KVCache, rate-limit windows, small lookups
VectorizeEmbeddings / retrieval (prego_ai)
LogpushCentralized logs (operator setup)

5.2 Multi-tenancy

  • tenant_id isolation is mandatory for tenant-scoped data paths.
  • R2 (example layout): tenants/{tenant_id}/files/{file_id}
  • Vectorize metadata: include tenant_id (and project_id, doc_id as required by the product) — see AI Worker docs and tenant trust.

6. Shared packages (required direction)

Monorepo layout (names may match existing packages/*):

packages/
ui/ # shared components
forms/ # shared form primitives + RHF helpers
contracts/ # Zod schemas + inferred types (source of truth for cross-app contracts)
api-client/ # typed clients for Zuplo-facing calls
config/ # shared env-safe config helpers

6.1 contracts (core)

  • Zod schemas for requests/responses shared by www / admin / client where applicable
  • Single place for breaking-change discipline and tests

7. Deployment & CI

  • CI: GitHub Actions
  • Cloudflare: Wrangler; multi-env (dev / staging / prod)
  • Strategy:
AppStrategy
wwwPages — static export (next build --webpack, Next 16.0.x)
admin-webOpenNext + Worker (Next 16.0.x, next.config.mjs)
client-webnext-on-pages today; Unify on OpenNext-aligned Cloudflare strategy (recommended; phased — ADR)
  • Next tsconfig hygiene: @platform/next-dev-scripts exposes prego-strip-next-dev-types-from-tsconfig so tsc --noEmit does not follow stale .next/dev/types entries Next may inject into include. Root pnpm run verify:next-dev-scripts; CI .github/workflows/next-dev-scripts.yml. See Web app standardization plan §4.
  • Monorepo integration verify (shared packages + internal Starlight docs — does not build www / admin-web / client-web production bundles): root pnpm run build:verify. Starlight docs/ = MDXdocs/README.md · Dependency inspection §7. If docs astro build fails with missing chunks under docs/dist (e.g. renderers.mjs), run pnpm run build:docs:clean from the repo root — AGENTS.md. IDE guide · Dependency inspection §8.

8. Repository layout (monorepo vs satellites)

Prego monorepo:

apps/
www/
admin-web/
client-web/
packages/
...

Other repositories (prego_ai, prego-control-plane, prego-zuplo) own Workers, gateway, and Frappe is separate — the mental model is still: UI in Prego apps, contracts in shared packages, public APIs via OpenAPI + Zuplo.

Forbidden:

  • Performing Worker responsibilities inside an app without going through the agreed gateway/BFF rules
  • Duplicate OpenAPI definitions — prego-zuplo remains the merged public contract source
  • Undocumented HTTP handlers without schema at the boundary

9. Observability (target shape)

9.1 Log fields (illustrative)

{
"request_id": "...",
"tenant_id": "...",
"user_id": "...",
"endpoint": "...",
"latency_ms": 0,
"error": null
}

9.2 Storage

  • Logpush → R2 (where enabled)
  • Operator/debug UIs — out of band unless explicitly productized

10. Security & auth

  • JWT and session patterns follow each app’s existing implementation.
  • Zuplo performs edge policy; Workers perform service-level verification consistent with Tenant & trust boundaries.
  • URL tenant scope and token claims must agree — no cross-tenant dispatch from mismatched path vs JWT.

11. Documentation rules

  • Platform docs: docs/src/content/docs/ (this site).
  • On change: API contract → update OpenAPI in prego-zuplo first; schema/package changes → update this section or linked runbooks; architecture shifts → update diagrams (Mermaid below).

12. Mermaid diagrams (standard)

API flow

sequenceDiagram
  participant UI as Next UI
  participant Z as Zuplo
  participant W as Worker
  participant D as D1/R2/KV

  UI->>Z: HTTPS (public contract)
  Z->>W: Forward (trusted headers)
  W->>D: Query / write
  D-->>W: Result
  W-->>Z: JSON
  Z-->>UI: Response

Data flow

flowchart LR
  UI[Next apps] --> Z[Zuplo]
  Z --> W[Workers]
  W --> D1[(D1)]
  W --> R2[(R2)]
  W --> KV[(KV)]
  W --> V[(Vectorize)]

13. Refactoring rules

When touching the web tier:

  • Remove duplication; move to shared packages
  • Delete dead code
  • Move legacy / demo / non-canonical assets to archive/ (or equivalent) and label in README
  • Align on contracts package for shared types
  • Update OpenAPI and platform docs in the same change set when behavior is user-visible

14. IDE optimization

  • Every cross-app or external API shape should have a Zod schema (in contracts or next to the gateway consumer).
  • Modules — one clear responsibility per folder; no “grab bag” utils.
  • Comments — prefer JSDoc on public exports and non-obvious invariants; avoid redundant noise.

15. Five-point summary

  1. Next — UI and orchestration (not Worker domain logic).
  2. Workers — edge HTTP and service logic (Hono where standard).
  3. Zuplo — gateway policy and public routing (BFF exceptions are narrow and documented).
  4. Zod — center of schema-first contracts for the web tier.
  5. Shared packages — default for UI, forms, and contracts.

16. Versioning

VersionStatus
Draft v1.0Initial adopted standard; refine with implementation feedback

Next review: when Next major, OpenNext, or client-web deployment strategy milestones complete — see Web app standardization plan.


한국어 요약

Prego Web App Standard (Draft v1.0)www / admin-web / client-web 의 공통 규칙입니다. 공개 API는 기본 Zuplo 를 통하고, 쿠키·비밀·동일 출처 등은 API gateway & BFF governance얇은 BFF 예외를 따릅니다. 폼·입력은 RHF + Zod, 공유 계약은 packages/contracts 방향으로 모읍니다. admin-web 은 온보딩·결제·테넌트 등 계약 밀도가 가장 높은 앱으로 다룹니다. 배포는 www = Pages 정적, admin = OpenNext+Worker, client = OpenNext 계열로 수렴을 권장합니다. Next 가 tsconfig include 에 넣는 .next/dev/types@platform/next-dev-scripts (prego-strip-next-dev-types-from-tsconfig)로 정리 — 루트 pnpm run verify:next-dev-scripts, §7·표준화 계획 §4. 모노레포 통합 검증(pnpm run build:verify, 내부 Starlight docs 포함; 세 Next 앱 프로덕션 번들은 아님) — 내부 docs/MDXdocs/README.md · Dependency inspection §7. astro build chunk 오류 시(예: renderers.mjs) 루트 pnpm run build:docs:cleanAGENTS.md · IDE 가이드 · Dependency inspection §8. 이메일·OTP 스키마는 @platform/web-auth-schemas (authEmailSchema, authEmailStringSchema, otpCodeSchema) — www / admin-web / client-web 에 적용됨(§3.4, safe refactor status). 상세 실행·우선순위는 Web app standardization plan 과 함께 보세요.

Help