@percepta/create 3.0.1 → 3.1.2
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/README.md +16 -9
- package/dist/{chunk-GEVZERMP.js → chunk-CG7IJSB4.js} +33 -2
- package/dist/{chunk-R4FWPE4A.js → chunk-DCM7JOSC.js} +2 -2
- package/dist/index.js +281 -82
- package/dist/{init-Z4VGBHAK.js → init-XDWSYHYK.js} +1 -1
- package/dist/{status-MITGDLTT.js → status-BTHGN6QH.js} +1 -1
- package/dist/{sync-J4SFZHDX.js → sync-3Q27L7XZ.js} +1 -1
- package/dist/{upstream-AQI7P4EU.js → upstream-C5KFAHVR.js} +1 -1
- package/package.json +3 -2
- package/templates/monorepo/gitignore.template +1 -0
- package/templates/webapp/.github/workflows/__APP_NAME__-ryvn-release.yaml +3 -2
- package/templates/webapp/AGENTS.md +8 -2
- package/templates/webapp/Dockerfile +0 -1
- package/templates/webapp/README.md +1 -0
- package/templates/webapp/agent-skills/database.md +1 -0
- package/templates/webapp/agent-skills/deploy.md +45 -32
- package/templates/webapp/agent-skills/oneshot.md +3 -3
- package/templates/webapp/deploy/README.md +32 -6
- package/templates/webapp/deploy/ryvn/__APP_NAME__.service.yaml +0 -2
- package/templates/webapp/deploy/ryvn/environments/percepta-test/installations/__APP_NAME__.env.percepta-test.serviceinstallation.yaml +28 -31
- package/templates/webapp/drizzle.config.ts +15 -6
- package/templates/webapp/env.example.template +1 -0
- package/templates/webapp/eslint.config.mjs +8 -0
- package/templates/webapp/gitignore.template +1 -0
- package/templates/webapp/package.json.template +6 -6
- package/templates/webapp/scripts/open-ryvn-deploy-pr.ts +495 -0
- package/templates/webapp/scripts/seed.ts +1 -1
- package/templates/webapp/scripts/setup-database.ts +16 -1
- package/templates/webapp/scripts/start.sh +3 -2
- package/templates/webapp/src/app/(app)/layout.tsx +1 -5
- package/templates/webapp/src/app/(auth)/auth/signin/CredentialsSignInForm.tsx +11 -1
- package/templates/webapp/src/app/(auth)/auth/signup/CredentialsSignUpForm.tsx +113 -0
- package/templates/webapp/src/app/(auth)/auth/signup/page.tsx +30 -0
- package/templates/webapp/src/app/global-error.tsx +3 -1
- package/templates/webapp/src/components/FaroProvider.tsx +2 -4
- package/templates/webapp/src/components/form/FormItem.tsx +2 -2
- package/templates/webapp/src/config/getEnvConfig.ts +1 -0
- package/templates/webapp/src/drizzle/db.ts +5 -1
- package/templates/webapp/src/drizzle/migrations/0000_eager_grandmaster.sql +3 -3
- package/templates/webapp/src/drizzle/migrations/meta/0000_snapshot.json +7 -19
- package/templates/webapp/src/drizzle/searchPath.test.ts +21 -0
- package/templates/webapp/src/drizzle/searchPath.ts +16 -0
- package/templates/webapp/src/drizzle/ssl.ts +5 -0
- package/templates/webapp/src/lib/auth/index.ts +1 -1
- package/templates/webapp/src/lib/auth-client.ts +1 -1
- package/templates/webapp/src/services/observability/initFaro.ts +1 -1
- package/templates/webapp/src/styles/globals.css +0 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percepta/create",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.2",
|
|
4
4
|
"description": "Scaffold a new Mosaic package",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"tsup": "^8.4.0",
|
|
28
28
|
"typescript": "^5.7.3",
|
|
29
29
|
"vitest": "^4.0.0",
|
|
30
|
-
"@percepta/build": "0.4.
|
|
30
|
+
"@percepta/build": "0.4.1"
|
|
31
31
|
},
|
|
32
32
|
"engines": {
|
|
33
33
|
"node": ">=18.0.0"
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"license": "MIT",
|
|
48
48
|
"scripts": {
|
|
49
49
|
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
50
|
+
"create:local": "pnpm build && node dist/index.js",
|
|
50
51
|
"dev": "tsup src/index.ts --format esm --watch",
|
|
51
52
|
"typecheck": "tsc --noEmit",
|
|
52
53
|
"sync-template": "tsx scripts/sync-template.ts",
|
|
@@ -9,7 +9,7 @@ on:
|
|
|
9
9
|
- "packages/__APP_NAME__/scripts/**"
|
|
10
10
|
- "packages/__APP_NAME__/Dockerfile"
|
|
11
11
|
- "packages/__APP_NAME__/package.json"
|
|
12
|
-
- "pnpm-lock.yaml"
|
|
12
|
+
- "packages/__APP_NAME__/pnpm-lock.yaml"
|
|
13
13
|
- ".github/workflows/__APP_NAME__-ryvn-release.yaml"
|
|
14
14
|
pull_request:
|
|
15
15
|
branches:
|
|
@@ -19,7 +19,7 @@ on:
|
|
|
19
19
|
- "packages/__APP_NAME__/scripts/**"
|
|
20
20
|
- "packages/__APP_NAME__/Dockerfile"
|
|
21
21
|
- "packages/__APP_NAME__/package.json"
|
|
22
|
-
- "pnpm-lock.yaml"
|
|
22
|
+
- "packages/__APP_NAME__/pnpm-lock.yaml"
|
|
23
23
|
workflow_dispatch:
|
|
24
24
|
|
|
25
25
|
env:
|
|
@@ -66,6 +66,7 @@ jobs:
|
|
|
66
66
|
service_name: ${{ env.SERVICE_NAME }}
|
|
67
67
|
version: ${{ steps.generate-tag.outputs.version }}
|
|
68
68
|
build_only: ${{ !(github.ref == format('refs/heads/{0}', github.event.repository.default_branch) || steps.generate-tag.outputs.isPreview == 'true') }}
|
|
69
|
+
build_args: NPM_TOKEN=${{ secrets.NPM_TOKEN }}
|
|
69
70
|
ryvn_client_id: ${{ secrets.RYVN_CLIENT_ID }}
|
|
70
71
|
ryvn_client_secret: ${{ secrets.RYVN_CLIENT_SECRET }}
|
|
71
72
|
|
|
@@ -24,7 +24,7 @@ Next.js 15 full-stack application scaffolded from the Mosaic webapp template via
|
|
|
24
24
|
- Logger messages must be plain string literals, not variables or templates
|
|
25
25
|
- `no-process-env` is enforced — use `getEnvConfig()` from `src/config/`
|
|
26
26
|
- Use `@percepta/design` components before writing custom UI
|
|
27
|
-
-
|
|
27
|
+
- For loading/error states, use local UI or add `@percepta/components` if you want `AsyncContent`
|
|
28
28
|
- Tailwind CSS for all styling; icons from `lucide-react`
|
|
29
29
|
|
|
30
30
|
## Project Structure
|
|
@@ -114,10 +114,16 @@ export default [
|
|
|
114
114
|
|
|
115
115
|
Vitest config is also available via `@percepta/build/vitest`.
|
|
116
116
|
|
|
117
|
-
### @percepta/components — React Utilities
|
|
117
|
+
### @percepta/components — Optional React Utilities
|
|
118
118
|
|
|
119
119
|
Async data handling and hooks for React Query:
|
|
120
120
|
|
|
121
|
+
Install this package first if you want these helpers:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
pnpm add @percepta/components
|
|
125
|
+
```
|
|
126
|
+
|
|
121
127
|
- **`AsyncContent<T>`** — renders loading spinner, error state, or children based on a React Query result. Use this for all data-fetching UI.
|
|
122
128
|
- **`AsyncArrayContent<T[]>`** — same but for multiple parallel queries
|
|
123
129
|
- **`ErrorContainer`** — consistent error display
|
|
@@ -45,7 +45,6 @@ ENV BASE_PATH=${BASE_PATH}
|
|
|
45
45
|
# Copy built app from builder stage
|
|
46
46
|
COPY --from=builder /app/.next/standalone ./
|
|
47
47
|
COPY --from=builder /app/.next/static ./.next/static
|
|
48
|
-
COPY --from=builder /app/public ./public
|
|
49
48
|
|
|
50
49
|
# Copy scripts and source files needed for start.sh and runtime
|
|
51
50
|
COPY --from=builder /app/scripts ./scripts
|
|
@@ -134,6 +134,7 @@ pnpm db:seed
|
|
|
134
134
|
| `DATABASE_USERNAME` | Database user | `postgres` |
|
|
135
135
|
| `DATABASE_PASSWORD` | Database password | `postgres` |
|
|
136
136
|
| `DATABASE_NAME` | Database name | `__DB_NAME__` |
|
|
137
|
+
| `DATABASE_SCHEMA` | Optional Postgres schema/search path | - |
|
|
137
138
|
| `DATABASE_USE_SSL` | Enable SSL | `false` |
|
|
138
139
|
|
|
139
140
|
### Security
|
|
@@ -130,6 +130,7 @@ pnpm docker:down
|
|
|
130
130
|
| `DATABASE_USERNAME` | `postgres` | Database user |
|
|
131
131
|
| `DATABASE_PASSWORD` | `postgres` | Database password |
|
|
132
132
|
| `DATABASE_NAME` | `__DB_NAME__` | Database name |
|
|
133
|
+
| `DATABASE_SCHEMA` | - | Optional Postgres schema/search path |
|
|
133
134
|
| `DATABASE_USE_SSL` | `false` | Enable SSL connections |
|
|
134
135
|
|
|
135
136
|
## Key Concepts
|
|
@@ -10,7 +10,7 @@ When this app was created with `@percepta/create`, the IaC files were generated
|
|
|
10
10
|
- `deploy/ryvn/environments/percepta-test/installations/__APP_NAME__.env.percepta-test.serviceinstallation.yaml` — percepta-test installation
|
|
11
11
|
- `.github/workflows/__APP_NAME__-ryvn-release.yaml` (at the repo root) — release workflow that builds the Docker image and creates a Ryvn release on push to `main`. Path filter scoped to `packages/__APP_NAME__/` so unrelated changes don't trigger builds.
|
|
12
12
|
|
|
13
|
-
Per-app values (URLs, k8s service names, database
|
|
13
|
+
Per-app values (URLs, k8s service names, database schema) are substituted at create-time. The Better Auth and encryption secrets are written to `deploy/ryvn/percepta-test.secrets.env`, which is ignored by git and intended for Ryvn UI import. Shared platform values (Inngest and OTel endpoints) are baked in as literals because they're stable across percepta-test apps.
|
|
14
14
|
|
|
15
15
|
See [`deploy/README.md`](../deploy/README.md) for the file-by-file breakdown.
|
|
16
16
|
|
|
@@ -19,51 +19,62 @@ See [`deploy/README.md`](../deploy/README.md) for the file-by-file breakdown.
|
|
|
19
19
|
- The app repo is under the `Percepta-Core` GitHub org. If not yet, run `gh repo create Percepta-Core/__APP_NAME__ --private --source=. --push` from the monorepo root.
|
|
20
20
|
- The Percepta-Core org has `RYVN_CLIENT_ID`, `RYVN_CLIENT_SECRET`, and `NPM_TOKEN` as org-level GitHub secrets (already in place).
|
|
21
21
|
- The `percepta-internal-terraform` installation provides the shared PostgreSQL — already deployed on percepta-test.
|
|
22
|
-
-
|
|
22
|
+
- `git` and `gh` are installed and authenticated.
|
|
23
|
+
- The infra repo (`Percepta-Core/infra`) is checked out locally or can be cloned by the deploy script.
|
|
23
24
|
|
|
24
25
|
## Deploy
|
|
25
26
|
|
|
26
|
-
### Step 1: Open the infra PR
|
|
27
|
+
### Step 1: Open the service/schema infra PR
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
Run the generated deploy helper from this package directory:
|
|
29
30
|
|
|
30
31
|
```bash
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
cp deploy/ryvn/$NAME.service.yaml \
|
|
35
|
-
$INFRA/ryvn/$NAME.service.yaml
|
|
32
|
+
pnpm deploy:percepta-test -- --phase service --yes
|
|
33
|
+
```
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
$INFRA/ryvn/environments/percepta-test/installations/$NAME.env.percepta-test.serviceinstallation.yaml
|
|
35
|
+
This script:
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
gh pr create --fill
|
|
46
|
-
```
|
|
37
|
+
- uses `INFRA_REPO` or `--infra <path>` when provided
|
|
38
|
+
- otherwise uses a sibling `../infra` checkout, cloning `Percepta-Core/infra` there if needed
|
|
39
|
+
- copies the Ryvn service YAML into infra
|
|
40
|
+
- appends a `postgresql_schema "__APP_NAME_SNAKE__"` resource to `terraform/percepta-internal/databases.tf`
|
|
41
|
+
- opens the first PR against `Percepta-Core/infra`
|
|
47
42
|
|
|
48
43
|
Get the PR reviewed and merged.
|
|
49
44
|
|
|
50
|
-
### Step 2:
|
|
45
|
+
### Step 2: Wait for service/schema import
|
|
51
46
|
|
|
52
|
-
After the
|
|
47
|
+
After the service/schema PR merges, wait for Ryvn GitOps to import the service. If Ryvn creates a `percepta-internal-terraform` task for the database schema, approve/apply it in Ryvn.
|
|
53
48
|
|
|
54
|
-
|
|
55
|
-
|--------|-------|
|
|
56
|
-
| `BETTER_AUTH_SECRET` | `openssl rand -base64 32` |
|
|
57
|
-
| `ENCRYPTION_SECRET_KEY` | `openssl rand -hex 16` |
|
|
58
|
-
| `LANGFUSE_SECRET_KEY` | from 1Password: "Percepta Test Secrets" |
|
|
49
|
+
### Step 3: Create the first release
|
|
59
50
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
Push to `main` in the app repo (or `gh workflow run "Build & Release __APP_NAME__"`). The release workflow builds the Docker image and creates a Ryvn release; Ryvn deploys it to percepta-test.
|
|
51
|
+
Push to `main` in the app repo (or `gh workflow run "Build & Release __APP_NAME__"`). The release workflow builds the Docker image and creates a Ryvn release. Do this before creating the ServiceInstallation, otherwise GitOps can fail with `ReleaseNotFound`.
|
|
63
52
|
|
|
64
53
|
The workflow lives at `.github/workflows/__APP_NAME__-ryvn-release.yaml` (at the repo root, where GitHub Actions picks it up). It only fires on changes under `packages/__APP_NAME__/`, so unrelated edits to other packages in the monorepo won't trigger it.
|
|
65
54
|
|
|
66
|
-
### Step 4:
|
|
55
|
+
### Step 4: Open the installation infra PR
|
|
56
|
+
|
|
57
|
+
After the first release exists, open the installation PR:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pnpm deploy:percepta-test -- --phase installation --yes
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The `--` is the pnpm argument delimiter; it passes `--phase` and `--yes` through to the deploy helper script.
|
|
64
|
+
|
|
65
|
+
Get the PR reviewed and merged. Ryvn GitOps will import the ServiceInstallation and the Staging channel should deploy the latest release.
|
|
66
|
+
|
|
67
|
+
### Step 5: Import Ryvn secrets
|
|
68
|
+
|
|
69
|
+
After GitOps imports the installation, import this generated file in the Ryvn UI for the installation secrets:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
deploy/ryvn/percepta-test.secrets.env
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Also set any app-specific secrets the implementation added, such as `OPENAI_API_KEY`.
|
|
76
|
+
|
|
77
|
+
### Step 6: Verify
|
|
67
78
|
|
|
68
79
|
```bash
|
|
69
80
|
ryvn get installation __APP_NAME__ -e percepta-test
|
|
@@ -76,16 +87,18 @@ The app will be available at **https://__APP_NAME__.percepta-test.aitco.dev**.
|
|
|
76
87
|
|
|
77
88
|
## Troubleshooting
|
|
78
89
|
|
|
79
|
-
- **
|
|
90
|
+
- **Auth/sign-in routes fail after install** → import `deploy/ryvn/percepta-test.secrets.env` in the Ryvn UI, then let Ryvn update/restart the installation.
|
|
91
|
+
- **Pod crash-looping** → check `ryvn logs`; migration or database connectivity failures are the most common fresh-deploy causes.
|
|
80
92
|
- **Database connection refused** → verify `DATABASE_USE_SSL=true` and that `percepta-internal-terraform` is deployed.
|
|
93
|
+
- **Database schema missing** → verify the infra PR added `postgresql_schema "__APP_NAME_SNAKE__"` and Ryvn applied `percepta-internal-terraform`.
|
|
81
94
|
- **Inngest can't reach the app** → `INNGEST_APP_URL` must use the k8s service name `__APP_NAME__-web-server`. The scaffolded YAML gets this right; if you renamed anything, double-check.
|
|
82
|
-
- **Image build fails** → check `NPM_TOKEN`
|
|
95
|
+
- **Image build fails fetching @percepta packages** → check the `NPM_TOKEN` GitHub org secret. The workflow passes it as a build arg.
|
|
83
96
|
|
|
84
97
|
For Ryvn CLI operations, use the `/use-ryvn` skill.
|
|
85
98
|
|
|
86
99
|
## Updating shared platform values
|
|
87
100
|
|
|
88
|
-
The Inngest
|
|
101
|
+
The Inngest and OTel URLs are baked as literals in every webapp's installation YAML. If percepta-test infra ever changes those endpoints, update them with a single grep across the infra repo:
|
|
89
102
|
|
|
90
103
|
```bash
|
|
91
104
|
grep -rl "inngest.percepta-test.svc.cluster.local:8288" ryvn/environments/percepta-test/installations/
|
|
@@ -122,7 +122,7 @@ If it fails, fix the errors before moving to the next chunk. Do not accumulate b
|
|
|
122
122
|
### Implementation Rules
|
|
123
123
|
|
|
124
124
|
- **Use `@percepta/design` components.** Do not write custom UI for things that exist in the design system (Button, Dialog, Table, Card, Input, etc.). Read `node_modules/@percepta/design/dist/src/index.d.ts` to see what's available.
|
|
125
|
-
- **Use
|
|
125
|
+
- **Use robust loading states.** `@percepta/components` is optional; add it first if you want `AsyncContent`.
|
|
126
126
|
- **Use `getEnvConfig()` for env vars.** Never use `process.env` directly.
|
|
127
127
|
- **Use `getLogger()` for logging.** Never use `console.log`. Use safe/unsafe field separation.
|
|
128
128
|
- **Follow the singleton pattern** for new services. Follow the existing `DatabaseService` singleton pattern in the codebase.
|
|
@@ -179,8 +179,8 @@ git init
|
|
|
179
179
|
git add -A
|
|
180
180
|
git commit -m "Initial implementation of <app-name>"
|
|
181
181
|
|
|
182
|
-
# Create the repo under
|
|
183
|
-
gh repo create
|
|
182
|
+
# Create the repo under the Percepta-Core org
|
|
183
|
+
gh repo create Percepta-Core/<app-name> --private --source=. --push
|
|
184
184
|
```
|
|
185
185
|
|
|
186
186
|
If `gh` is not authenticated, tell the user to run `gh auth login` and then continue.
|
|
@@ -12,21 +12,47 @@ deploy/
|
|
|
12
12
|
└── __APP_NAME__.env.percepta-test.serviceinstallation.yaml # percepta-test installation
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
These files are pre-filled with all values needed to deploy to `https://__APP_NAME__.percepta-test.aitco.dev`. The
|
|
15
|
+
These files are pre-filled with all base values needed to deploy to `https://__APP_NAME__.percepta-test.aitco.dev`. The generated deploy helper opens the required `Percepta-Core/infra` PRs in two phases.
|
|
16
16
|
|
|
17
17
|
## Deploying
|
|
18
18
|
|
|
19
|
-
Tell Claude "deploy this app to percepta-test" — it'll follow [`agent-skills/deploy.md`](../agent-skills/deploy.md), which
|
|
19
|
+
Tell Claude "deploy this app to percepta-test" — it'll follow [`agent-skills/deploy.md`](../agent-skills/deploy.md), which runs the generated PR helper and then verifies Ryvn.
|
|
20
20
|
|
|
21
21
|
## What's in these files
|
|
22
22
|
|
|
23
|
-
**`__APP_NAME__.service.yaml`** — tells Ryvn how to build the Docker image. Points at `Percepta-Core/__APP_NAME__` (change the repo if you've named the GitHub repo differently). The `NPM_TOKEN`
|
|
23
|
+
**`__APP_NAME__.service.yaml`** — tells Ryvn how to build the Docker image. Points at `Percepta-Core/__APP_NAME__` (change the repo if you've named the GitHub repo differently). The release workflow passes `NPM_TOKEN` as a build arg from GitHub org secrets.
|
|
24
24
|
|
|
25
25
|
**`__APP_NAME__.env.percepta-test.serviceinstallation.yaml`** — configures the deployment on `percepta-test`. Three categories of values are baked in:
|
|
26
26
|
|
|
27
|
-
1. **Per-app values** that vary by app name (URLs, k8s service names) — substituted at create-time.
|
|
28
|
-
2. **Shared platform values** (Inngest
|
|
29
|
-
3. **
|
|
27
|
+
1. **Per-app values** that vary by app name (URLs, k8s service names, database schema) — substituted at create-time.
|
|
28
|
+
2. **Shared platform values** (Inngest and OTel endpoints) — copied as literals from existing percepta-test installations. These are stable across percepta-test apps.
|
|
29
|
+
3. **Database wiring** — points at the shared `demos` database and a per-app schema created by the infra PR.
|
|
30
|
+
|
|
31
|
+
**`percepta-test.secrets.env`** — generated locally and ignored by git. Import it in the Ryvn UI for `BETTER_AUTH_SECRET` and `ENCRYPTION_SECRET_KEY`; deployment secret values are intentionally not committed to GitOps IaC.
|
|
32
|
+
|
|
33
|
+
## Deployment order
|
|
34
|
+
|
|
35
|
+
Use two infra PRs. The Service must exist before the first release can be created, and the first release must exist before the ServiceInstallation can be imported.
|
|
36
|
+
|
|
37
|
+
1. Open and merge the service/schema PR:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pnpm deploy:percepta-test -- --phase service --yes
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
2. Wait for GitOps to import the service. If the schema change creates a `percepta-internal-terraform` task in Ryvn, approve/apply it.
|
|
44
|
+
|
|
45
|
+
3. Push the app to `main` or run the release workflow so Ryvn has a first release for `__APP_NAME__`.
|
|
46
|
+
|
|
47
|
+
4. Open and merge the installation PR:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pnpm deploy:percepta-test -- --phase installation --yes
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
5. After GitOps imports the installation, import `deploy/ryvn/percepta-test.secrets.env` into the Ryvn UI for the `__APP_NAME__` installation secrets.
|
|
54
|
+
|
|
55
|
+
The `--` is the pnpm argument delimiter; it passes the flags after it through to `scripts/open-ryvn-deploy-pr.ts`.
|
|
30
56
|
|
|
31
57
|
## Repo layout note
|
|
32
58
|
|
|
@@ -10,8 +10,23 @@ spec:
|
|
|
10
10
|
service:
|
|
11
11
|
port: 3000
|
|
12
12
|
|
|
13
|
+
startupEnabled: true
|
|
14
|
+
startupProbe:
|
|
15
|
+
httpGet:
|
|
16
|
+
path: /api/healthz
|
|
17
|
+
port: 3000
|
|
18
|
+
failureThreshold: 30
|
|
19
|
+
periodSeconds: 10
|
|
13
20
|
livenessEnabled: true
|
|
21
|
+
livenessProbe:
|
|
22
|
+
httpGet:
|
|
23
|
+
path: /api/healthz
|
|
24
|
+
port: 3000
|
|
14
25
|
readinessEnabled: true
|
|
26
|
+
readinessProbe:
|
|
27
|
+
httpGet:
|
|
28
|
+
path: /api/readyz
|
|
29
|
+
port: 3000
|
|
15
30
|
|
|
16
31
|
resources:
|
|
17
32
|
requests:
|
|
@@ -38,29 +53,33 @@ spec:
|
|
|
38
53
|
- __APP_NAME__.percepta-test.aitco.dev
|
|
39
54
|
|
|
40
55
|
env:
|
|
41
|
-
# Database
|
|
56
|
+
# Database — shared `demos` DB on the percepta-internal Postgres instance.
|
|
57
|
+
# Tables live under a per-app schema created by the infra PR. DATABASE_SCHEMA
|
|
58
|
+
# pins the connection search_path so Drizzle migrations + queries land there.
|
|
42
59
|
- name: DATABASE_HOST
|
|
43
60
|
valueFrom:
|
|
44
61
|
secretKeyRef:
|
|
45
|
-
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.
|
|
62
|
+
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.percepta_internal_postgresql_secret_name }}"
|
|
46
63
|
key: host
|
|
47
64
|
- name: DATABASE_PORT
|
|
48
65
|
valueFrom:
|
|
49
66
|
secretKeyRef:
|
|
50
|
-
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.
|
|
67
|
+
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.percepta_internal_postgresql_secret_name }}"
|
|
51
68
|
key: port
|
|
52
69
|
- name: DATABASE_USERNAME
|
|
53
70
|
valueFrom:
|
|
54
71
|
secretKeyRef:
|
|
55
|
-
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.
|
|
72
|
+
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.percepta_internal_postgresql_secret_name }}"
|
|
56
73
|
key: username
|
|
57
74
|
- name: DATABASE_PASSWORD
|
|
58
75
|
valueFrom:
|
|
59
76
|
secretKeyRef:
|
|
60
|
-
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.
|
|
77
|
+
name: "{{ .ryvn.installations.percepta_internal_terraform.outputs.percepta_internal_postgresql_secret_name }}"
|
|
61
78
|
key: password
|
|
62
79
|
- name: DATABASE_NAME
|
|
63
|
-
value: "
|
|
80
|
+
value: "demos"
|
|
81
|
+
- name: DATABASE_SCHEMA
|
|
82
|
+
value: "__APP_NAME_SNAKE__"
|
|
64
83
|
- name: DATABASE_USE_SSL
|
|
65
84
|
value: "true"
|
|
66
85
|
|
|
@@ -74,14 +93,9 @@ spec:
|
|
|
74
93
|
value: https://__APP_NAME__.percepta-test.aitco.dev
|
|
75
94
|
- key: BETTER_AUTH_URL
|
|
76
95
|
value: https://__APP_NAME__.percepta-test.aitco.dev
|
|
77
|
-
|
|
78
|
-
#
|
|
79
|
-
|
|
80
|
-
isSecret: true
|
|
81
|
-
|
|
82
|
-
# Encryption — generated random, set in Ryvn UI (openssl rand -hex 16)
|
|
83
|
-
- key: ENCRYPTION_SECRET_KEY
|
|
84
|
-
isSecret: true
|
|
96
|
+
# Import BETTER_AUTH_SECRET and ENCRYPTION_SECRET_KEY from
|
|
97
|
+
# deploy/ryvn/percepta-test.secrets.env in the Ryvn UI after the installation
|
|
98
|
+
# exists. Secret values are intentionally not declared in GitOps IaC.
|
|
85
99
|
|
|
86
100
|
# Inngest (shared percepta-test instance)
|
|
87
101
|
- key: INNGEST_BASE_URL
|
|
@@ -95,14 +109,6 @@ spec:
|
|
|
95
109
|
- key: INNGEST_SERVE_HOST
|
|
96
110
|
value: http://__APP_NAME__-web-server.percepta-test.svc.cluster.local:3000/api/inngest
|
|
97
111
|
|
|
98
|
-
# Langfuse (shared percepta-test instance) — secret key set in Ryvn UI from 1Password
|
|
99
|
-
- key: LANGFUSE_BASE_URL
|
|
100
|
-
value: https://percepta-test.aitco.dev/evals
|
|
101
|
-
- key: LANGFUSE_PUBLIC_KEY
|
|
102
|
-
value: pk-lf-cc45f2c9-5286-4966-849b-42fd45059390
|
|
103
|
-
- key: LANGFUSE_SECRET_KEY
|
|
104
|
-
isSecret: true
|
|
105
|
-
|
|
106
112
|
# OpenTelemetry
|
|
107
113
|
- key: OTEL_METRICS_EXPORTER_OTLP_ENDPOINT
|
|
108
114
|
value: http://otel-collector-opentelemetry-collector.percepta-test.svc.cluster.local:4318/v1/metrics
|
|
@@ -110,12 +116,3 @@ spec:
|
|
|
110
116
|
value: "60000"
|
|
111
117
|
- key: LOG_LEVEL
|
|
112
118
|
value: debug
|
|
113
|
-
|
|
114
|
-
# Set the values for these in the Ryvn UI after the infra PR merges:
|
|
115
|
-
# BETTER_AUTH_SECRET — generate: openssl rand -base64 32
|
|
116
|
-
# ENCRYPTION_SECRET_KEY — generate: openssl rand -hex 16
|
|
117
|
-
# LANGFUSE_SECRET_KEY — copy from 1Password "Percepta Test Secrets"
|
|
118
|
-
secrets:
|
|
119
|
-
- name: BETTER_AUTH_SECRET
|
|
120
|
-
- name: ENCRYPTION_SECRET_KEY
|
|
121
|
-
- name: LANGFUSE_SECRET_KEY
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { loadEnvConfig } from "@next/env";
|
|
2
2
|
import type { Config } from "drizzle-kit";
|
|
3
3
|
import { getEnvConfig } from "./src/config/getEnvConfig";
|
|
4
|
+
import { getPgSearchPathOption } from "./src/drizzle/searchPath";
|
|
4
5
|
|
|
5
6
|
loadEnvConfig(process.cwd());
|
|
6
7
|
|
|
@@ -10,20 +11,28 @@ const {
|
|
|
10
11
|
DATABASE_USERNAME: user,
|
|
11
12
|
DATABASE_PASSWORD: password,
|
|
12
13
|
DATABASE_NAME: database,
|
|
14
|
+
DATABASE_SCHEMA: databaseSchema,
|
|
13
15
|
DATABASE_USE_SSL: useSSL,
|
|
14
16
|
} = getEnvConfig();
|
|
15
17
|
|
|
18
|
+
const schemaFilter = databaseSchema?.trim() || undefined;
|
|
19
|
+
const searchPathOption = getPgSearchPathOption(schemaFilter);
|
|
20
|
+
const connectionParams = new URLSearchParams();
|
|
21
|
+
if (useSSL) connectionParams.set("sslmode", "require");
|
|
22
|
+
if (searchPathOption) connectionParams.set("options", searchPathOption);
|
|
23
|
+
|
|
24
|
+
const connectionString =
|
|
25
|
+
`postgresql://${encodeURIComponent(user)}:${encodeURIComponent(password)}` +
|
|
26
|
+
`@${host}:${port}/${encodeURIComponent(database)}` +
|
|
27
|
+
(connectionParams.size > 0 ? `?${connectionParams.toString()}` : "");
|
|
28
|
+
|
|
16
29
|
const config: Config = {
|
|
17
30
|
schema: "./src/drizzle/schema",
|
|
18
31
|
out: "./src/drizzle/migrations",
|
|
19
32
|
dialect: "postgresql",
|
|
33
|
+
...(schemaFilter ? { schemaFilter: [schemaFilter] } : {}),
|
|
20
34
|
dbCredentials: {
|
|
21
|
-
|
|
22
|
-
port,
|
|
23
|
-
user,
|
|
24
|
-
password,
|
|
25
|
-
database,
|
|
26
|
-
ssl: useSSL ? "require" : false,
|
|
35
|
+
url: connectionString,
|
|
27
36
|
},
|
|
28
37
|
};
|
|
29
38
|
|
|
@@ -11,6 +11,7 @@ export default [
|
|
|
11
11
|
{
|
|
12
12
|
ignores: [
|
|
13
13
|
"pnpm-lock.yaml",
|
|
14
|
+
"package.json",
|
|
14
15
|
".next/**",
|
|
15
16
|
"next-env.d.ts",
|
|
16
17
|
"public/**",
|
|
@@ -24,6 +25,7 @@ export default [
|
|
|
24
25
|
rules: {
|
|
25
26
|
...nextPlugin.configs.recommended.rules,
|
|
26
27
|
...nextPlugin.configs["core-web-vitals"].rules,
|
|
28
|
+
"react/react-in-jsx-scope": "off",
|
|
27
29
|
},
|
|
28
30
|
},
|
|
29
31
|
{
|
|
@@ -49,4 +51,10 @@ export default [
|
|
|
49
51
|
"n/no-process-env": "error",
|
|
50
52
|
},
|
|
51
53
|
},
|
|
54
|
+
{
|
|
55
|
+
files: ["src/config/clientEnvConfig.ts"],
|
|
56
|
+
rules: {
|
|
57
|
+
"n/no-process-env": "off",
|
|
58
|
+
},
|
|
59
|
+
},
|
|
52
60
|
];
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"db:studio": "drizzle-kit studio",
|
|
22
22
|
"db:create-user": "tsx ./scripts/create-user.ts",
|
|
23
23
|
"db:seed": "tsx ./scripts/seed.ts",
|
|
24
|
+
"deploy:percepta-test": "tsx ./scripts/open-ryvn-deploy-pr.ts",
|
|
24
25
|
"test": "vitest run",
|
|
25
26
|
"test:watch": "vitest"
|
|
26
27
|
},
|
|
@@ -47,11 +48,10 @@
|
|
|
47
48
|
"@opentelemetry/api": "^1.9.0",
|
|
48
49
|
"@opentelemetry/auto-instrumentations-node": "^0.62.1",
|
|
49
50
|
"@opentelemetry/sdk-node": "^0.203.0",
|
|
50
|
-
"@percepta/design": "
|
|
51
|
-
"@percepta/
|
|
52
|
-
"@percepta/
|
|
53
|
-
"@percepta/
|
|
54
|
-
"@percepta/utils": "^0.1.5",
|
|
51
|
+
"@percepta/design": "0.3.2",
|
|
52
|
+
"@percepta/logger": "0.0.6",
|
|
53
|
+
"@percepta/next-utils": "0.1.0",
|
|
54
|
+
"@percepta/utils": "0.1.10",
|
|
55
55
|
"@radix-ui/react-slot": "^1.2.3",
|
|
56
56
|
"@tanstack/react-query": "^5.81.5",
|
|
57
57
|
"@tanstack/react-virtual": "^3.13.12",
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
97
|
"@next/eslint-plugin-next": "^15.3.5",
|
|
98
|
-
"@percepta/build": "
|
|
98
|
+
"@percepta/build": "0.4.0",
|
|
99
99
|
"@tailwindcss/postcss": "^4.1.11",
|
|
100
100
|
"@types/formidable": "^3.4.5",
|
|
101
101
|
"@types/he": "^1.2.3",
|