create-sailor 1.4.0 → 1.4.1

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.
Files changed (57) hide show
  1. package/dist/index.js +224 -207
  2. package/package.json +2 -1
  3. package/templates/deploy/Dockerfile.web +57 -0
  4. package/templates/deploy/docker-compose.yml +40 -0
  5. package/templates/deploy/railway.toml +13 -0
  6. package/templates/deploy/vercel.json +37 -0
  7. package/templates/deploy/wrangler.toml +8 -0
  8. package/templates/docs/docusaurus/README.md +24 -0
  9. package/templates/docs/docusaurus/docs/getting-started/develop.md +20 -0
  10. package/templates/docs/docusaurus/docs/getting-started/install.md +11 -0
  11. package/templates/docs/docusaurus/docs/intro.md +15 -0
  12. package/templates/docs/docusaurus/docusaurus.config.ts +66 -0
  13. package/templates/docs/docusaurus/package.json +43 -0
  14. package/templates/docs/docusaurus/sidebars.ts +14 -0
  15. package/templates/docs/docusaurus/src/css/custom.css +22 -0
  16. package/templates/docs/docusaurus/tsconfig.json +7 -0
  17. package/templates/docs/fumadocs/README.md +46 -0
  18. package/templates/docs/fumadocs/app/(home)/page.tsx +22 -0
  19. package/templates/docs/fumadocs/app/api/search/route.ts +4 -0
  20. package/templates/docs/fumadocs/app/docs/[[...slug]]/page.tsx +39 -0
  21. package/templates/docs/fumadocs/app/docs/layout.tsx +11 -0
  22. package/templates/docs/fumadocs/app/global.css +10 -0
  23. package/templates/docs/fumadocs/app/layout.tsx +18 -0
  24. package/templates/docs/fumadocs/content/docs/api.mdx +31 -0
  25. package/templates/docs/fumadocs/content/docs/concepts.mdx +19 -0
  26. package/templates/docs/fumadocs/content/docs/getting-started.mdx +56 -0
  27. package/templates/docs/fumadocs/content/docs/index.mdx +17 -0
  28. package/templates/docs/fumadocs/content/docs/meta.json +4 -0
  29. package/templates/docs/fumadocs/lib/source.ts +7 -0
  30. package/templates/docs/fumadocs/next.config.mjs +17 -0
  31. package/templates/docs/fumadocs/package.json +30 -0
  32. package/templates/docs/fumadocs/source.config.ts +17 -0
  33. package/templates/docs/fumadocs/tsconfig.json +25 -0
  34. package/templates/docs/mintlify/README.md +25 -0
  35. package/templates/docs/mintlify/api-reference/introduction.mdx +25 -0
  36. package/templates/docs/mintlify/introduction.mdx +21 -0
  37. package/templates/docs/mintlify/mint.json +37 -0
  38. package/templates/docs/mintlify/package.json +13 -0
  39. package/templates/docs/mintlify/quickstart.mdx +26 -0
  40. package/templates/docs/nextra/README.md +35 -0
  41. package/templates/docs/nextra/app/[[...mdxPath]]/page.tsx +23 -0
  42. package/templates/docs/nextra/app/layout.tsx +36 -0
  43. package/templates/docs/nextra/content/_meta.ts +4 -0
  44. package/templates/docs/nextra/content/getting-started.mdx +35 -0
  45. package/templates/docs/nextra/content/index.mdx +18 -0
  46. package/templates/docs/nextra/mdx-components.tsx +10 -0
  47. package/templates/docs/nextra/next.config.mjs +9 -0
  48. package/templates/docs/nextra/package.json +24 -0
  49. package/templates/docs/nextra/tsconfig.json +21 -0
  50. package/templates/docs/vitepress/.vitepress/config.ts +35 -0
  51. package/templates/docs/vitepress/README.md +23 -0
  52. package/templates/docs/vitepress/guide/getting-started.md +26 -0
  53. package/templates/docs/vitepress/guide/introduction.md +12 -0
  54. package/templates/docs/vitepress/index.md +23 -0
  55. package/templates/docs/vitepress/package.json +17 -0
  56. package/templates/docs/vitepress/tsconfig.json +15 -0
  57. package/dist/index.d.ts +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-sailor",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "Governed AI-native SaaS scaffolder for Nebutra Sailor. Bootstrap a production-ready Next.js + Hono + Prisma monorepo with multi-tenant foundations, region-aware defaults, and AI integrations.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -9,6 +9,7 @@
9
9
  },
10
10
  "files": [
11
11
  "dist",
12
+ "templates",
12
13
  "README.md",
13
14
  "LICENSE"
14
15
  ],
@@ -0,0 +1,57 @@
1
+ FROM node:22-alpine AS base
2
+
3
+ # Install dependencies only when needed
4
+ FROM base AS deps
5
+ RUN apk add --no-cache libc6-compat
6
+ WORKDIR /app
7
+
8
+ # Enable corepack for pnpm
9
+ RUN corepack enable pnpm
10
+
11
+ COPY package.json pnpm-lock.yaml* ./
12
+ COPY turbo.json ./
13
+ COPY patches ./patches
14
+ COPY apps/web/package.json ./apps/web/
15
+ COPY backends/gateway/package.json ./backends/gateway/
16
+ COPY packages/*/package.json ./packages/
17
+ RUN pnpm install --frozen-lockfile
18
+
19
+ # Rebuild the source code only when needed
20
+ FROM base AS builder
21
+ WORKDIR /app
22
+ RUN corepack enable pnpm
23
+ COPY --from=deps /app/node_modules ./node_modules
24
+ COPY . .
25
+
26
+ # Pass nextjs env vars for build time if necessary
27
+ ENV NEXT_TELEMETRY_DISABLED 1
28
+ RUN pnpm run build
29
+
30
+ # Production image, copy all the files and run next
31
+ FROM base AS runner
32
+ WORKDIR /app
33
+
34
+ ENV NODE_ENV production
35
+ ENV NEXT_TELEMETRY_DISABLED 1
36
+
37
+ RUN addgroup --system --gid 1001 nodejs
38
+ RUN adduser --system --uid 1001 nextjs
39
+
40
+ # Set the correct permission for prerender cache
41
+ RUN mkdir .next
42
+ RUN chown nextjs:nodejs .next
43
+
44
+ # Automatically leverage output traces to reduce image size
45
+ # https://nextjs.org/docs/advanced-features/output-file-tracing
46
+ COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/standalone ./
47
+ COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static
48
+ COPY --from=builder --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public
49
+
50
+ USER nextjs
51
+
52
+ EXPOSE 3000
53
+
54
+ ENV PORT 3000
55
+ ENV HOSTNAME "0.0.0.0"
56
+
57
+ CMD ["node", "apps/web/server.js"]
@@ -0,0 +1,40 @@
1
+ version: '3.8'
2
+
3
+ services:
4
+ web:
5
+ build:
6
+ context: .
7
+ dockerfile: Dockerfile.web
8
+ ports:
9
+ - "3000:3000"
10
+ environment:
11
+ - DATABASE_URL=postgresql://postgres:postgres@db:5432/nebutra
12
+ - REDIS_URL=redis://redis:6379
13
+ depends_on:
14
+ - db
15
+ - redis
16
+ restart: always
17
+
18
+ db:
19
+ image: postgres:15-alpine
20
+ environment:
21
+ - POSTGRES_USER=postgres
22
+ - POSTGRES_PASSWORD=postgres
23
+ - POSTGRES_DB=nebutra
24
+ ports:
25
+ - "5432:5432"
26
+ volumes:
27
+ - pgdata:/var/lib/postgresql/data
28
+ restart: always
29
+
30
+ redis:
31
+ image: redis:7-alpine
32
+ ports:
33
+ - "6379:6379"
34
+ volumes:
35
+ - redisdata:/data
36
+ restart: always
37
+
38
+ volumes:
39
+ pgdata:
40
+ redisdata:
@@ -0,0 +1,13 @@
1
+ [build]
2
+ builder = "NIXPACKS"
3
+ buildCommand = "pnpm build"
4
+
5
+ [build.nixpacksPlan.phases.setup]
6
+ nixPkgs = ["...", "pnpm-8_x"]
7
+
8
+ [deploy]
9
+ startCommand = "pnpm start"
10
+ healthcheckPath = "/api/health"
11
+ healthcheckTimeout = 100
12
+ restartPolicyType = "ON_FAILURE"
13
+ restartPolicyMaxRetries = 5
@@ -0,0 +1,37 @@
1
+ {
2
+ "version": 2,
3
+ "buildCommand": "pnpm build",
4
+ "ignoreCommand": "bash ./scripts/ignore-build-step.sh",
5
+ "framework": "nextjs",
6
+ "crons": [
7
+ {
8
+ "path": "/api/webhooks/cron/daily",
9
+ "schedule": "0 0 * * *"
10
+ }
11
+ ],
12
+ "headers": [
13
+ {
14
+ "source": "/(.*)",
15
+ "headers": [
16
+ {
17
+ "key": "X-Content-Type-Options",
18
+ "value": "nosniff"
19
+ },
20
+ {
21
+ "key": "X-Frame-Options",
22
+ "value": "DENY"
23
+ },
24
+ {
25
+ "key": "X-XSS-Protection",
26
+ "value": "1; mode=block"
27
+ }
28
+ ]
29
+ }
30
+ ],
31
+ "rewrites": [
32
+ {
33
+ "source": "/api/auth/:path*",
34
+ "destination": "/api/auth/:path*"
35
+ }
36
+ ]
37
+ }
@@ -0,0 +1,8 @@
1
+ name = "nebutra-sailor"
2
+ compatibility_date = "2024-03-20"
3
+ compatibility_flags = ["nodejs_compat"]
4
+ pages_build_output_dir = ".opennext"
5
+
6
+ [env.production]
7
+ # Add your production variables here
8
+ # DATABASE_URL = "postgress://..."
@@ -0,0 +1,24 @@
1
+ # {PRODUCT_NAME} Docs
2
+
3
+ Documentation site for {PRODUCT_NAME}, built with [Docusaurus 3](https://docusaurus.io/).
4
+
5
+ ## Develop
6
+
7
+ ```bash
8
+ pnpm install
9
+ pnpm dev # http://localhost:3001
10
+ ```
11
+
12
+ ## Add a page
13
+
14
+ 1. Drop a `.md` or `.mdx` file under `docs/`
15
+ 2. Add the path to `sidebars.ts` (or use auto-generated sidebars)
16
+
17
+ ## Deploy
18
+
19
+ ```bash
20
+ pnpm build # static output -> build/
21
+ pnpm serve # preview locally
22
+ ```
23
+
24
+ The `build/` directory can be hosted on any static host (Vercel, Cloudflare Pages, S3, GitHub Pages).
@@ -0,0 +1,20 @@
1
+ ---
2
+ sidebar_position: 2
3
+ ---
4
+
5
+ # Develop
6
+
7
+ ```bash
8
+ pnpm dev # http://localhost:3001
9
+ ```
10
+
11
+ The site rebuilds on file change. New pages: drop a `.md` or `.mdx` under `docs/` and add it to `sidebars.ts`.
12
+
13
+ ## Build for production
14
+
15
+ ```bash
16
+ pnpm build
17
+ pnpm serve
18
+ ```
19
+
20
+ The static output is written to `build/` — host it on any CDN.
@@ -0,0 +1,11 @@
1
+ ---
2
+ sidebar_position: 1
3
+ ---
4
+
5
+ # Install
6
+
7
+ ```bash
8
+ pnpm install
9
+ ```
10
+
11
+ That's it — Docusaurus has no separate setup step.
@@ -0,0 +1,15 @@
1
+ ---
2
+ sidebar_position: 1
3
+ slug: /
4
+ ---
5
+
6
+ # Welcome to {PRODUCT_NAME}
7
+
8
+ This is the documentation site for **{PRODUCT_NAME}**, scaffolded by [create-sailor](https://github.com/Nebutra/Nebutra-Sailor) with [Docusaurus 3](https://docusaurus.io/).
9
+
10
+ ## What's next
11
+
12
+ - [Install dependencies](./getting-started/install.md)
13
+ - [Run the dev server](./getting-started/develop.md)
14
+
15
+ Edit `docs/intro.md` to change this page.
@@ -0,0 +1,66 @@
1
+ import type * as Preset from "@docusaurus/preset-classic";
2
+ import type { Config } from "@docusaurus/types";
3
+ import { themes as prismThemes } from "prism-react-renderer";
4
+
5
+ const config: Config = {
6
+ title: "{PRODUCT_NAME}",
7
+ tagline: "Documentation for {PRODUCT_NAME}",
8
+ favicon: "img/favicon.ico",
9
+
10
+ url: "https://docs.example.com",
11
+ baseUrl: "/",
12
+
13
+ organizationName: "your-org",
14
+ projectName: "your-repo",
15
+
16
+ onBrokenLinks: "throw",
17
+ onBrokenMarkdownLinks: "warn",
18
+
19
+ i18n: {
20
+ defaultLocale: "en",
21
+ locales: ["en"],
22
+ },
23
+
24
+ presets: [
25
+ [
26
+ "classic",
27
+ {
28
+ docs: {
29
+ sidebarPath: "./sidebars.ts",
30
+ editUrl: "https://github.com/your-org/your-repo/tree/main/docs/",
31
+ routeBasePath: "/",
32
+ },
33
+ blog: false,
34
+ theme: {
35
+ customCss: "./src/css/custom.css",
36
+ },
37
+ } satisfies Preset.Options,
38
+ ],
39
+ ],
40
+
41
+ themeConfig: {
42
+ image: "img/social-card.png",
43
+ navbar: {
44
+ title: "{PRODUCT_NAME}",
45
+ logo: { alt: "{PRODUCT_NAME}", src: "img/logo.svg" },
46
+ items: [
47
+ { type: "docSidebar", sidebarId: "tutorialSidebar", position: "left", label: "Docs" },
48
+ {
49
+ href: "https://github.com/your-org/your-repo",
50
+ label: "GitHub",
51
+ position: "right",
52
+ },
53
+ ],
54
+ },
55
+ footer: {
56
+ style: "dark",
57
+ copyright: "Copyright © " + new Date().getFullYear() + " {PRODUCT_NAME}.",
58
+ },
59
+ prism: {
60
+ theme: prismThemes.github,
61
+ darkTheme: prismThemes.dracula,
62
+ },
63
+ } satisfies Preset.ThemeConfig,
64
+ };
65
+
66
+ export default config;
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@nebutra/docs",
3
+ "private": true,
4
+ "version": "0.0.1",
5
+ "scripts": {
6
+ "dev": "docusaurus start --port 3001",
7
+ "start": "docusaurus start --port 3001",
8
+ "build": "docusaurus build",
9
+ "serve": "docusaurus serve --port 3001",
10
+ "typecheck": "tsc --noEmit",
11
+ "clear": "docusaurus clear"
12
+ },
13
+ "dependencies": {
14
+ "@docusaurus/core": "^3.7.0",
15
+ "@docusaurus/preset-classic": "^3.7.0",
16
+ "@mdx-js/react": "^3.0.1",
17
+ "clsx": "^2.1.1",
18
+ "prism-react-renderer": "^2.4.1",
19
+ "react": "^19.0.0",
20
+ "react-dom": "^19.0.0"
21
+ },
22
+ "devDependencies": {
23
+ "@docusaurus/module-type-aliases": "^3.7.0",
24
+ "@docusaurus/tsconfig": "^3.7.0",
25
+ "@docusaurus/types": "^3.7.0",
26
+ "typescript": "^5.9.3"
27
+ },
28
+ "browserslist": {
29
+ "production": [
30
+ ">0.5%",
31
+ "not dead",
32
+ "not op_mini all"
33
+ ],
34
+ "development": [
35
+ "last 3 chrome version",
36
+ "last 3 firefox version",
37
+ "last 5 safari version"
38
+ ]
39
+ },
40
+ "engines": {
41
+ "node": ">=20.0.0"
42
+ }
43
+ }
@@ -0,0 +1,14 @@
1
+ import type { SidebarsConfig } from "@docusaurus/plugin-content-docs";
2
+
3
+ const sidebars: SidebarsConfig = {
4
+ tutorialSidebar: [
5
+ "intro",
6
+ {
7
+ type: "category",
8
+ label: "Getting started",
9
+ items: ["getting-started/install", "getting-started/develop"],
10
+ },
11
+ ],
12
+ };
13
+
14
+ export default sidebars;
@@ -0,0 +1,22 @@
1
+ :root {
2
+ --ifm-color-primary: #0033fe;
3
+ --ifm-color-primary-dark: #002de5;
4
+ --ifm-color-primary-darker: #002bd9;
5
+ --ifm-color-primary-darkest: #0023b3;
6
+ --ifm-color-primary-light: #1f4cff;
7
+ --ifm-color-primary-lighter: #2d57ff;
8
+ --ifm-color-primary-lightest: #5a78ff;
9
+ --ifm-code-font-size: 95%;
10
+ --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
11
+ }
12
+
13
+ [data-theme="dark"] {
14
+ --ifm-color-primary: #4d72ff;
15
+ --ifm-color-primary-dark: #2d57ff;
16
+ --ifm-color-primary-darker: #1f4cff;
17
+ --ifm-color-primary-darkest: #0033fe;
18
+ --ifm-color-primary-light: #6d8aff;
19
+ --ifm-color-primary-lighter: #7d97ff;
20
+ --ifm-color-primary-lightest: #adbfff;
21
+ --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
22
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "@docusaurus/tsconfig",
3
+ "compilerOptions": {
4
+ "baseUrl": "."
5
+ },
6
+ "exclude": [".docusaurus", "build"]
7
+ }
@@ -0,0 +1,46 @@
1
+ # {PRODUCT_NAME} Docs
2
+
3
+ Documentation site for {PRODUCT_NAME}, built with [Fumadocs](https://fumadocs.vercel.app/) + Next.js 16 + Tailwind v4.
4
+
5
+ ## Run locally
6
+
7
+ ```bash
8
+ pnpm --filter @nebutra/docs dev
9
+ ```
10
+
11
+ Opens on http://localhost:3001.
12
+
13
+ ## Edit content
14
+
15
+ MDX source lives in `content/docs/`. Each file becomes a page under `/docs/<slug>`.
16
+
17
+ - Add a new page → create `content/docs/my-page.mdx`
18
+ - Control sidebar order → edit `content/docs/meta.json`
19
+ - Use built-in components (`<Cards>`, `<Card>`, `<Tabs>`, `<Tab>`, `<Callout>`, etc.) directly in MDX — they come from `fumadocs-ui/mdx`.
20
+
21
+ ## Customize
22
+
23
+ - **Branding / colors**: wired to `@nebutra/tokens` via `app/global.css`. Edit tokens centrally, not here.
24
+ - **Sidebar / nav**: `app/docs/layout.tsx` — `DocsLayout` props.
25
+ - **Search**: `app/api/search/route.ts` auto-indexes all MDX via `createFromSource`.
26
+ - **MDX plugins**: `source.config.ts` → `mdxOptions`.
27
+
28
+ Full Fumadocs reference: https://fumadocs.vercel.app/docs.
29
+
30
+ ## 2026 docs best practices
31
+
32
+ This template follows Nebutra docs best-practices, encoded as MDX comments inline in each starter page:
33
+
34
+ - **Home** — hero + 3-6 cards, no marketing fluff
35
+ - **Getting Started** — single goal: 5-minute first example (Install → Initialize → Hello World → Next steps)
36
+ - **Concepts** — explains the "why" / mental model, not steps, not APIs
37
+ - **API Reference** — auto-generated from OpenAPI; every endpoint has method badge + params + schema + multi-language examples
38
+
39
+ When refreshing the API reference inputs:
40
+
41
+ ```bash
42
+ pnpm --filter @nebutra/gateway generate:spec
43
+ pnpm generate:api-types
44
+ ```
45
+
46
+ Then replace `content/docs/api.mdx` with generated reference content sourced from `backends/gateway/openapi.json`.
@@ -0,0 +1,22 @@
1
+ import Link from "next/link";
2
+
3
+ export const dynamic = "force-static";
4
+
5
+ export default function HomePage() {
6
+ return (
7
+ <main className="flex flex-1 flex-col items-center justify-center gap-6 px-4 py-24 text-center">
8
+ <h1 className="text-4xl font-bold tracking-tight sm:text-5xl">
9
+ {"{PRODUCT_NAME}"} Documentation
10
+ </h1>
11
+ <p className="max-w-xl text-lg text-fd-muted-foreground">
12
+ Build AI-native SaaS products faster. Everything you need to ship is documented here.
13
+ </p>
14
+ <Link
15
+ href="/docs"
16
+ className="rounded-md bg-fd-primary px-6 py-3 font-semibold text-fd-primary-foreground transition-opacity hover:opacity-90"
17
+ >
18
+ Read the docs
19
+ </Link>
20
+ </main>
21
+ );
22
+ }
@@ -0,0 +1,4 @@
1
+ import { createFromSource } from "fumadocs-core/search/server";
2
+ import { source } from "@/lib/source";
3
+
4
+ export const { GET } = createFromSource(source);
@@ -0,0 +1,39 @@
1
+ import defaultMdxComponents from "fumadocs-ui/mdx";
2
+ import { DocsBody, DocsDescription, DocsPage, DocsTitle } from "fumadocs-ui/page";
3
+ import { notFound } from "next/navigation";
4
+ import { source } from "@/lib/source";
5
+
6
+ export const dynamic = "force-static";
7
+
8
+ export default async function Page(props: { params: Promise<{ slug?: string[] }> }) {
9
+ const params = await props.params;
10
+ const page = source.getPage(params.slug);
11
+ if (!page) notFound();
12
+
13
+ const MDX = page.data.body;
14
+
15
+ return (
16
+ <DocsPage toc={page.data.toc} full={page.data.full}>
17
+ <DocsTitle>{page.data.title}</DocsTitle>
18
+ <DocsDescription>{page.data.description}</DocsDescription>
19
+ <DocsBody>
20
+ <MDX components={{ ...defaultMdxComponents }} />
21
+ </DocsBody>
22
+ </DocsPage>
23
+ );
24
+ }
25
+
26
+ export function generateStaticParams() {
27
+ return source.generateParams();
28
+ }
29
+
30
+ export async function generateMetadata(props: { params: Promise<{ slug?: string[] }> }) {
31
+ const params = await props.params;
32
+ const page = source.getPage(params.slug);
33
+ if (!page) notFound();
34
+
35
+ return {
36
+ title: page.data.title,
37
+ description: page.data.description,
38
+ };
39
+ }
@@ -0,0 +1,11 @@
1
+ import { DocsLayout } from "fumadocs-ui/layouts/docs";
2
+ import type { ReactNode } from "react";
3
+ import { source } from "@/lib/source";
4
+
5
+ export default function Layout({ children }: { children: ReactNode }) {
6
+ return (
7
+ <DocsLayout tree={source.pageTree} nav={{ title: "{PRODUCT_NAME}" }}>
8
+ {children}
9
+ </DocsLayout>
10
+ );
11
+ }
@@ -0,0 +1,10 @@
1
+ @import "tailwindcss";
2
+ @import "fumadocs-ui/css/neutral.css";
3
+ @import "fumadocs-ui/css/preset.css";
4
+
5
+ /* Pull in Nebutra design tokens (brand colors, semantic scales, gradients). */
6
+ @import "@nebutra/tokens/styles.css";
7
+
8
+ /* Tell Tailwind v4 to scan @nebutra/ui source so its utility classes compile. */
9
+ @source "../node_modules/@nebutra/ui/src/**/*.{ts,tsx}";
10
+ @source "../node_modules/fumadocs-ui/dist/**/*.js";
@@ -0,0 +1,18 @@
1
+ import { RootProvider } from "fumadocs-ui/provider";
2
+ import type { ReactNode } from "react";
3
+ import "./global.css";
4
+
5
+ export const metadata = {
6
+ title: "{PRODUCT_NAME} Docs",
7
+ description: "Documentation for {PRODUCT_NAME}",
8
+ };
9
+
10
+ export default function RootLayout({ children }: { children: ReactNode }) {
11
+ return (
12
+ <html lang="en" suppressHydrationWarning>
13
+ <body className="flex min-h-screen flex-col">
14
+ <RootProvider>{children}</RootProvider>
15
+ </body>
16
+ </html>
17
+ );
18
+ }
@@ -0,0 +1,31 @@
1
+ ---
2
+ title: API Reference
3
+ description: Complete API documentation
4
+ ---
5
+
6
+ {/* 2026 BEST PRACTICE: API Reference should be auto-generated from OpenAPI spec */}
7
+ {/* 2026 BEST PRACTICE: Every endpoint needs: Method badge, params table, response schema, multi-language examples */}
8
+ {/* TODO: Export backends/gateway/openapi.json and replace this starter page with generated reference content. */}
9
+
10
+ # API Reference
11
+
12
+ API documentation is easiest to maintain when it is generated from your OpenAPI spec.
13
+
14
+ To refresh the source spec and the shared TypeScript types in `apps/web`:
15
+
16
+ ```bash
17
+ pnpm --filter @nebutra/gateway generate:spec
18
+ pnpm generate:api-types
19
+ ```
20
+
21
+ ## Endpoints
22
+
23
+ ### GET /hello
24
+
25
+ Returns a hello message.
26
+
27
+ **Response**:
28
+
29
+ ```json
30
+ { "message": "Hello, world!" }
31
+ ```
@@ -0,0 +1,19 @@
1
+ ---
2
+ title: Concepts
3
+ description: Core mental models and design decisions
4
+ ---
5
+
6
+ {/* 2026 BEST PRACTICE: Concepts explains the "why" and mental model */}
7
+ {/* 2026 BEST PRACTICE: Don't explain steps — that's Guides. Don't list APIs — that's API Reference */}
8
+
9
+ # Concepts
10
+
11
+ Understand the core models and design decisions.
12
+
13
+ ## Workspaces
14
+
15
+ A workspace is...
16
+
17
+ ## Authentication
18
+
19
+ ...
@@ -0,0 +1,56 @@
1
+ ---
2
+ title: Getting Started
3
+ description: Run your first example in 5 minutes
4
+ ---
5
+
6
+ {/* 2026 BEST PRACTICE: Getting Started's ONLY goal is 5-minute first example */}
7
+ {/* 2026 BEST PRACTICE: No architecture explanation here — that belongs in Concepts */}
8
+ {/* 2026 BEST PRACTICE: Structure: Install → Initialize → Hello World → Next steps */}
9
+
10
+ # Getting Started
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm install @your-product/sdk
16
+ ```
17
+
18
+ ## Initialize
19
+
20
+ ```ts title="src/index.ts"
21
+ import { YourProduct } from '@your-product/sdk';
22
+
23
+ const client = new YourProduct({
24
+ apiKey: process.env.YOUR_API_KEY,
25
+ });
26
+ ```
27
+
28
+ ## Hello World
29
+
30
+ <Tabs items={['TypeScript', 'Python', 'cURL']}>
31
+ <Tab value="TypeScript">
32
+ ```ts
33
+ const result = await client.hello();
34
+ console.log(result);
35
+ ```
36
+ </Tab>
37
+ <Tab value="Python">
38
+ ```python
39
+ result = client.hello()
40
+ print(result)
41
+ ```
42
+ </Tab>
43
+ <Tab value="cURL">
44
+ ```bash
45
+ curl https://api.your-product.com/hello \
46
+ -H "Authorization: Bearer $YOUR_API_KEY"
47
+ ```
48
+ </Tab>
49
+ </Tabs>
50
+
51
+ ## Next steps
52
+
53
+ <Cards>
54
+ <Card title="Concepts" href="/docs/concepts" />
55
+ <Card title="API Reference" href="/docs/api" />
56
+ </Cards>