@reaatech/prompt-version-control-server 0.1.0
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/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/README.md +261 -0
- package/dist/api/routes/deployments.d.ts +4 -0
- package/dist/api/routes/deployments.d.ts.map +1 -0
- package/dist/api/routes/deployments.js +48 -0
- package/dist/api/routes/deployments.js.map +1 -0
- package/dist/api/routes/docs.d.ts +4 -0
- package/dist/api/routes/docs.d.ts.map +1 -0
- package/dist/api/routes/docs.js +75 -0
- package/dist/api/routes/docs.js.map +1 -0
- package/dist/api/routes/evaluations.d.ts +4 -0
- package/dist/api/routes/evaluations.d.ts.map +1 -0
- package/dist/api/routes/evaluations.js +63 -0
- package/dist/api/routes/evaluations.js.map +1 -0
- package/dist/api/routes/metrics.d.ts +4 -0
- package/dist/api/routes/metrics.d.ts.map +1 -0
- package/dist/api/routes/metrics.js +38 -0
- package/dist/api/routes/metrics.js.map +1 -0
- package/dist/api/routes/promotions.d.ts +4 -0
- package/dist/api/routes/promotions.d.ts.map +1 -0
- package/dist/api/routes/promotions.js +95 -0
- package/dist/api/routes/promotions.js.map +1 -0
- package/dist/api/routes/prompts.d.ts +4 -0
- package/dist/api/routes/prompts.d.ts.map +1 -0
- package/dist/api/routes/prompts.js +80 -0
- package/dist/api/routes/prompts.js.map +1 -0
- package/dist/api/routes/render.d.ts +4 -0
- package/dist/api/routes/render.d.ts.map +1 -0
- package/dist/api/routes/render.js +44 -0
- package/dist/api/routes/render.js.map +1 -0
- package/dist/api/routes/tags.d.ts +4 -0
- package/dist/api/routes/tags.d.ts.map +1 -0
- package/dist/api/routes/tags.js +41 -0
- package/dist/api/routes/tags.js.map +1 -0
- package/dist/api/routes/webhooks.d.ts +4 -0
- package/dist/api/routes/webhooks.d.ts.map +1 -0
- package/dist/api/routes/webhooks.js +49 -0
- package/dist/api/routes/webhooks.js.map +1 -0
- package/dist/db/client.d.ts +3 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +21 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/redis.d.ts +3 -0
- package/dist/db/redis.d.ts.map +1 -0
- package/dist/db/redis.js +18 -0
- package/dist/db/redis.js.map +1 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +39 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +83 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/audit.d.ts +3 -0
- package/dist/middleware/audit.d.ts.map +1 -0
- package/dist/middleware/audit.js +39 -0
- package/dist/middleware/audit.js.map +1 -0
- package/dist/middleware/auth.d.ts +3 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +49 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +3 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +36 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/metrics.d.ts +3 -0
- package/dist/middleware/metrics.d.ts.map +1 -0
- package/dist/middleware/metrics.js +13 -0
- package/dist/middleware/metrics.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +8 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +89 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/middleware/request-id.d.ts +3 -0
- package/dist/middleware/request-id.d.ts.map +1 -0
- package/dist/middleware/request-id.js +10 -0
- package/dist/middleware/request-id.js.map +1 -0
- package/dist/services/audit.service.d.ts +6 -0
- package/dist/services/audit.service.d.ts.map +1 -0
- package/dist/services/audit.service.js +26 -0
- package/dist/services/audit.service.js.map +1 -0
- package/dist/services/deployment.service.d.ts +101 -0
- package/dist/services/deployment.service.d.ts.map +1 -0
- package/dist/services/deployment.service.js +127 -0
- package/dist/services/deployment.service.js.map +1 -0
- package/dist/services/diff.engine.d.ts +13 -0
- package/dist/services/diff.engine.d.ts.map +1 -0
- package/dist/services/diff.engine.js +101 -0
- package/dist/services/diff.engine.js.map +1 -0
- package/dist/services/eval.service.d.ts +55 -0
- package/dist/services/eval.service.d.ts.map +1 -0
- package/dist/services/eval.service.js +151 -0
- package/dist/services/eval.service.js.map +1 -0
- package/dist/services/event.bus.d.ts +18 -0
- package/dist/services/event.bus.d.ts.map +1 -0
- package/dist/services/event.bus.js +35 -0
- package/dist/services/event.bus.js.map +1 -0
- package/dist/services/metric.service.d.ts +33 -0
- package/dist/services/metric.service.d.ts.map +1 -0
- package/dist/services/metric.service.js +64 -0
- package/dist/services/metric.service.js.map +1 -0
- package/dist/services/prometheus.service.d.ts +7 -0
- package/dist/services/prometheus.service.d.ts.map +1 -0
- package/dist/services/prometheus.service.js +27 -0
- package/dist/services/prometheus.service.js.map +1 -0
- package/dist/services/prompt.service.d.ts +59 -0
- package/dist/services/prompt.service.d.ts.map +1 -0
- package/dist/services/prompt.service.js +144 -0
- package/dist/services/prompt.service.js.map +1 -0
- package/dist/services/tag.service.d.ts +46 -0
- package/dist/services/tag.service.d.ts.map +1 -0
- package/dist/services/tag.service.js +84 -0
- package/dist/services/tag.service.js.map +1 -0
- package/dist/services/webhook.service.d.ts +50 -0
- package/dist/services/webhook.service.d.ts.map +1 -0
- package/dist/services/webhook.service.js +196 -0
- package/dist/services/webhook.service.js.map +1 -0
- package/dist/types/hono.d.ts +10 -0
- package/dist/types/hono.d.ts.map +1 -0
- package/dist/types/hono.js +2 -0
- package/dist/types/hono.js.map +1 -0
- package/dist/utils/context.d.ts +3 -0
- package/dist/utils/context.d.ts.map +1 -0
- package/dist/utils/context.js +9 -0
- package/dist/utils/context.js.map +1 -0
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +20 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/pagination.d.ts +10 -0
- package/dist/utils/pagination.d.ts.map +1 -0
- package/dist/utils/pagination.js +10 -0
- package/dist/utils/pagination.js.map +1 -0
- package/package.json +74 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# @reaatech/prompt-version-control-server
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Initial release
|
|
6
|
+
|
|
7
|
+
- Hono-based API server with Prisma + PostgreSQL persistence and Redis caching
|
|
8
|
+
- Prompt and version CRUD with SHA-256 checksums and automatic version numbering
|
|
9
|
+
- Tag-based lifecycle (`draft`, `staging`, `production`) with eval-gated promotion
|
|
10
|
+
- A/B deployments with weighted traffic splitting and sticky sessions
|
|
11
|
+
- Semantic diffing with line-level diffs and impact scoring
|
|
12
|
+
- Per-version metrics ingestion (cost, latency, quality)
|
|
13
|
+
- Structured Pino logging and a Prometheus `/metrics` endpoint
|
|
14
|
+
- OpenAPI 3.0 spec served at `/api/v1/docs`
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 prompt-version-control contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# @reaatech/prompt-version-control-server
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@reaatech/prompt-version-control-server)
|
|
4
|
+
[](https://github.com/reaatech/prompt-version-control/blob/main/LICENSE)
|
|
5
|
+
[](https://github.com/reaatech/prompt-version-control/actions/workflows/ci.yml)
|
|
6
|
+
|
|
7
|
+
> **Status:** Pre-1.0 — APIs may change in minor versions. Pin to a specific version in production.
|
|
8
|
+
|
|
9
|
+
Prompt Version Control API server providing Git-like versioning for AI prompts with eval-gated promotion, A/B deployment, metrics collection, and webhook integrations. Built on [Hono 4](https://hono.dev) with [Prisma](https://prisma.io) and PostgreSQL.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @reaatech/prompt-version-control-server
|
|
15
|
+
# or
|
|
16
|
+
pnpm add @reaatech/prompt-version-control-server
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Feature Overview
|
|
20
|
+
|
|
21
|
+
- **Prompt CRUD** — create, read, update, and archive prompts with automatic version numbering
|
|
22
|
+
- **Version management** — store and track prompt versions with SHA-256 checksums for deduplication
|
|
23
|
+
- **Tag-based lifecycle** — resolve versions by `draft`, `staging`, and `production` tags
|
|
24
|
+
- **Evaluation gates** — block staging→production promotion on eval harness results
|
|
25
|
+
- **A/B deployments** — serve multiple versions with weighted traffic splitting and sticky sessions
|
|
26
|
+
- **Semantic diffing** — compare versions with line-level diffs and semantic impact scoring
|
|
27
|
+
- **Metrics ingestion** — track per-version cost, latency, and quality metrics
|
|
28
|
+
- **Promotion workflows** — promote/rollback production with audit trails
|
|
29
|
+
- **Webhook subscriptions** — notify external systems on version creation, tag changes, and evaluations
|
|
30
|
+
- **Structured logging** — Pino-based JSON logging with automatic pretty-printing in development
|
|
31
|
+
- **Prometheus metrics** — built-in `/metrics` endpoint for monitoring
|
|
32
|
+
- **API key auth** — scoped API keys with HMAC verification and audit logging
|
|
33
|
+
- **Swagger UI** — OpenAPI 3.0 spec served at `/api/v1/docs`
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
### Development
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Set up environment
|
|
41
|
+
cp .env.example .env
|
|
42
|
+
|
|
43
|
+
# Install dependencies
|
|
44
|
+
pnpm install
|
|
45
|
+
|
|
46
|
+
# Generate Prisma client
|
|
47
|
+
pnpm --filter @reaatech/prompt-version-control-server db:generate
|
|
48
|
+
|
|
49
|
+
# Run migrations
|
|
50
|
+
pnpm --filter @reaatech/prompt-version-control-server db:migrate
|
|
51
|
+
|
|
52
|
+
# Seed the database
|
|
53
|
+
pnpm --filter @reaatech/prompt-version-control-server db:seed
|
|
54
|
+
|
|
55
|
+
# Start development server with hot reload
|
|
56
|
+
pnpm --filter @reaatech/prompt-version-control-server dev
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Programmatic
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { app } from "@reaatech/prompt-version-control-server";
|
|
63
|
+
import { serve } from "@hono/node-server";
|
|
64
|
+
|
|
65
|
+
serve({ fetch: app.fetch, port: 3000 }, (info) => {
|
|
66
|
+
console.log(`Server running on http://localhost:${info.port}`);
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## API Reference
|
|
71
|
+
|
|
72
|
+
### Infrastructure Endpoints
|
|
73
|
+
|
|
74
|
+
| Method | Path | Description |
|
|
75
|
+
|--------|------|-------------|
|
|
76
|
+
| `GET` | `/health` | Health check — returns `{ status: "ok", timestamp }` |
|
|
77
|
+
| `GET` | `/ready` | Readiness check — returns `{ status: "ready" }` |
|
|
78
|
+
| `GET` | `/metrics` | Prometheus text-format metrics |
|
|
79
|
+
| `GET` | `/api/v1/docs` | Swagger UI |
|
|
80
|
+
| `GET` | `/api/v1/docs/openapi.yaml` | Raw OpenAPI 3.0 spec |
|
|
81
|
+
|
|
82
|
+
All API routes are prefixed with `/api/v1` and require `Authorization: Bearer <api-key>` unless noted.
|
|
83
|
+
|
|
84
|
+
### Prompts
|
|
85
|
+
|
|
86
|
+
| Method | Path | Description |
|
|
87
|
+
|--------|------|-------------|
|
|
88
|
+
| `GET` | `/api/v1/prompts` | List prompts (paginated: `?limit=20&cursor=...`) |
|
|
89
|
+
| `POST` | `/api/v1/prompts` | Create prompt |
|
|
90
|
+
| `GET` | `/api/v1/prompts/:id` | Get prompt by ID |
|
|
91
|
+
| `PUT` | `/api/v1/prompts/:id` | Update prompt |
|
|
92
|
+
| `DELETE` | `/api/v1/prompts/:id` | Archive prompt |
|
|
93
|
+
| `GET` | `/api/v1/prompts/:id/versions` | List versions for prompt (paginated) |
|
|
94
|
+
| `POST` | `/api/v1/prompts/:id/versions` | Create version (auto-increments `number`) |
|
|
95
|
+
| `GET` | `/api/v1/prompts/:id/versions/:vid` | Get specific version |
|
|
96
|
+
| `GET` | `/api/v1/prompts/:id/production` | Get production-tagged version |
|
|
97
|
+
| `GET` | `/api/v1/prompts/:id/diff` | Diff two versions (`?fromVersion=X&toVersion=Y`) |
|
|
98
|
+
|
|
99
|
+
### Tags
|
|
100
|
+
|
|
101
|
+
| Method | Path | Description |
|
|
102
|
+
|--------|------|-------------|
|
|
103
|
+
| `GET` | `/api/v1/prompts/:id/tags` | List tags for prompt |
|
|
104
|
+
| `POST` | `/api/v1/prompts/:id/tags/:name` | Set tag to a version (`{ versionId }` in body) |
|
|
105
|
+
| `GET` | `/api/v1/prompts/:id/tags/:name` | Get tag details |
|
|
106
|
+
| `DELETE` | `/api/v1/prompts/:id/tags/:name` | Remove tag |
|
|
107
|
+
|
|
108
|
+
Tag names: `draft`, `staging`, `production`. Only one version can hold a given tag at a time.
|
|
109
|
+
|
|
110
|
+
### Promotions
|
|
111
|
+
|
|
112
|
+
| Method | Path | Description |
|
|
113
|
+
|--------|------|-------------|
|
|
114
|
+
| `POST` | `/api/v1/prompts/:id/promote` | Promote staging → production (gated by eval) |
|
|
115
|
+
| `POST` | `/api/v1/prompts/:id/promote/override` | Force-promote a specific version (`{ versionId }` in body) |
|
|
116
|
+
| `POST` | `/api/v1/prompts/:id/rollback` | Rollback production to previous version |
|
|
117
|
+
|
|
118
|
+
The `promote` endpoint checks the evaluation gate: if the staging version has failed evaluations, the promotion is blocked.
|
|
119
|
+
|
|
120
|
+
### Evaluations
|
|
121
|
+
|
|
122
|
+
| Method | Path | Description |
|
|
123
|
+
|--------|------|-------------|
|
|
124
|
+
| `POST` | `/api/v1/evaluations/webhook` | Receive eval harness webhook (public, HMAC-authenticated) |
|
|
125
|
+
| `POST` | `/api/v1/evaluations/trigger` | Trigger evaluation (`{ versionId }` in body) |
|
|
126
|
+
| `GET` | `/api/v1/evaluations/versions/:versionId` | List evaluations for a version |
|
|
127
|
+
| `GET` | `/api/v1/evaluations/versions/:versionId/gate` | Get promotion gate status |
|
|
128
|
+
|
|
129
|
+
### Metrics
|
|
130
|
+
|
|
131
|
+
| Method | Path | Description |
|
|
132
|
+
|--------|------|-------------|
|
|
133
|
+
| `POST` | `/api/v1/metrics/ingest` | Ingest metrics (array of metric objects in body) |
|
|
134
|
+
| `GET` | `/api/v1/metrics/versions/:versionId` | Get metrics for version (`?hours=24` optional) |
|
|
135
|
+
| `GET` | `/api/v1/metrics/prompts/:promptId` | Get metrics for prompt (`?hours=24` optional) |
|
|
136
|
+
|
|
137
|
+
Metric types: `cost`, `latency`, `quality`.
|
|
138
|
+
|
|
139
|
+
### Deployments
|
|
140
|
+
|
|
141
|
+
| Method | Path | Description |
|
|
142
|
+
|--------|------|-------------|
|
|
143
|
+
| `POST` | `/api/v1/deployments` | Create deployment with weighted variants |
|
|
144
|
+
| `GET` | `/api/v1/deployments` | List deployments (`?promptId=` filter optional) |
|
|
145
|
+
| `GET` | `/api/v1/deployments/:id/resolve` | Resolve version for session (`?sessionId=`) |
|
|
146
|
+
| `PUT` | `/api/v1/deployments/:id` | Update deployment status (`active`/`paused`/`archived`) |
|
|
147
|
+
|
|
148
|
+
### Render
|
|
149
|
+
|
|
150
|
+
| Method | Path | Description |
|
|
151
|
+
|--------|------|-------------|
|
|
152
|
+
| `POST` | `/api/v1/prompts/:id/versions/:number/render` | Render specific version with variables |
|
|
153
|
+
| `POST` | `/api/v1/prompts/:id/render` | Render production version with variables |
|
|
154
|
+
|
|
155
|
+
Both accept `{ variables: Record<string, unknown> }` in the body and return the rendered output with variable usage metadata.
|
|
156
|
+
|
|
157
|
+
### Webhooks
|
|
158
|
+
|
|
159
|
+
| Method | Path | Description |
|
|
160
|
+
|--------|------|-------------|
|
|
161
|
+
| `POST` | `/api/v1/webhooks` | Create webhook subscription |
|
|
162
|
+
| `GET` | `/api/v1/webhooks` | List subscriptions |
|
|
163
|
+
| `DELETE` | `/api/v1/webhooks/:id` | Delete subscription |
|
|
164
|
+
| `POST` | `/api/v1/webhooks/:id/test` | Test delivery |
|
|
165
|
+
|
|
166
|
+
### Middleware Stack
|
|
167
|
+
|
|
168
|
+
All API routes pass through:
|
|
169
|
+
|
|
170
|
+
| Middleware | Description |
|
|
171
|
+
|------------|-------------|
|
|
172
|
+
| `requestIdMiddleware` | Assigns `requestId` to every request context |
|
|
173
|
+
| `compress()` | gzip/deflate response compression |
|
|
174
|
+
| `cors()` | Configurable via `CORS_ALLOWED_ORIGINS` env var |
|
|
175
|
+
| `rateLimit()` | 100 requests per 60-second window per IP |
|
|
176
|
+
| `metricsMiddleware` | Prometheus metrics collection |
|
|
177
|
+
| `auth` | Bearer API key verification via HMAC |
|
|
178
|
+
|
|
179
|
+
### Environment Variables
|
|
180
|
+
|
|
181
|
+
| Variable | Required | Default | Description |
|
|
182
|
+
|----------|----------|---------|-------------|
|
|
183
|
+
| `DATABASE_URL` | Yes | — | PostgreSQL connection string |
|
|
184
|
+
| `REDIS_URL` | Yes | — | Redis connection string |
|
|
185
|
+
| `NODE_ENV` | No | `development` | Environment (`development` enables pretty logging) |
|
|
186
|
+
| `PORT` | No | `3000` | Server listen port |
|
|
187
|
+
| `LOG_LEVEL` | No | `info` | Pino log level |
|
|
188
|
+
| `JWT_SECRET` | No | — | HMAC pepper for API key hashing |
|
|
189
|
+
| `API_KEY_PEPPER` | No | — | Additional pepper for API key HMAC |
|
|
190
|
+
| `EVAL_WEBHOOK_SECRET` | No | — | HMAC secret for eval webhook verification |
|
|
191
|
+
| `CORS_ALLOWED_ORIGINS` | No | `*` | CORS allowed origins |
|
|
192
|
+
|
|
193
|
+
## Usage Patterns
|
|
194
|
+
|
|
195
|
+
### Create a Prompt with Versions
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
# Create a prompt
|
|
199
|
+
curl -X POST http://localhost:3000/api/v1/prompts \
|
|
200
|
+
-H "Authorization: Bearer pvc_your-api-key" \
|
|
201
|
+
-H "Content-Type: application/json" \
|
|
202
|
+
-d '{
|
|
203
|
+
"name": "customer-support",
|
|
204
|
+
"template": "You are a helpful support agent. Help with: {{issue}}"
|
|
205
|
+
}'
|
|
206
|
+
|
|
207
|
+
# Create a version
|
|
208
|
+
curl -X POST http://localhost:3000/api/v1/prompts/<promptId>/versions \
|
|
209
|
+
-H "Authorization: Bearer pvc_your-api-key" \
|
|
210
|
+
-H "Content-Type: application/json" \
|
|
211
|
+
-d '{
|
|
212
|
+
"content": "You are a senior support agent. Help with: {{issue}}"
|
|
213
|
+
}'
|
|
214
|
+
|
|
215
|
+
# Tag as production
|
|
216
|
+
curl -X POST http://localhost:3000/api/v1/prompts/<promptId>/tags/production \
|
|
217
|
+
-H "Authorization: Bearer pvc_your-api-key" \
|
|
218
|
+
-H "Content-Type: application/json" \
|
|
219
|
+
-d '{ "versionId": "<versionId>" }'
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Render a Prompt with Variables
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
curl -X POST http://localhost:3000/api/v1/prompts/<promptId>/render \
|
|
226
|
+
-H "Authorization: Bearer pvc_your-api-key" \
|
|
227
|
+
-H "Content-Type: application/json" \
|
|
228
|
+
-d '{
|
|
229
|
+
"variables": { "issue": "I cannot log in to my account" }
|
|
230
|
+
}'
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### A/B Deployment
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
curl -X POST http://localhost:3000/api/v1/deployments \
|
|
237
|
+
-H "Authorization: Bearer pvc_your-api-key" \
|
|
238
|
+
-H "Content-Type: application/json" \
|
|
239
|
+
-d '{
|
|
240
|
+
"promptId": "<promptId>",
|
|
241
|
+
"variants": [
|
|
242
|
+
{ "versionId": "<versionA>", "weight": 90 },
|
|
243
|
+
{ "versionId": "<versionB>", "weight": 10 }
|
|
244
|
+
]
|
|
245
|
+
}'
|
|
246
|
+
|
|
247
|
+
# Resolve for a session
|
|
248
|
+
curl "http://localhost:3000/api/v1/deployments/<deploymentId>/resolve?sessionId=user-123" \
|
|
249
|
+
-H "Authorization: Bearer pvc_your-api-key"
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Related Packages
|
|
253
|
+
|
|
254
|
+
- [`@reaatech/prompt-version-control-shared`](https://www.npmjs.com/package/@reaatech/prompt-version-control-shared) — Shared types and schemas
|
|
255
|
+
- [`@reaatech/prompt-version-control`](https://www.npmjs.com/package/@reaatech/prompt-version-control) — TypeScript SDK
|
|
256
|
+
- [`@reaatech/prompt-version-control-cli`](https://www.npmjs.com/package/@reaatech/prompt-version-control-cli) — CLI tool
|
|
257
|
+
- [`@reaatech/prompt-version-control-mcp`](https://www.npmjs.com/package/@reaatech/prompt-version-control-mcp) — MCP server for AI agents
|
|
258
|
+
|
|
259
|
+
## License
|
|
260
|
+
|
|
261
|
+
[MIT](https://github.com/reaatech/prompt-version-control/blob/main/LICENSE)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployments.d.ts","sourceRoot":"","sources":["../../../src/api/routes/deployments.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,QAAA,MAAM,MAAM,4EAAa,CAAC;AAuD1B,OAAO,EAAE,MAAM,IAAI,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { zValidator } from '@hono/zod-validator';
|
|
2
|
+
import { Hono } from 'hono';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { authMiddleware } from '../../middleware/auth.js';
|
|
5
|
+
import { deploymentService } from '../../services/deployment.service.js';
|
|
6
|
+
import { getProjectId } from '../../utils/context.js';
|
|
7
|
+
const router = new Hono();
|
|
8
|
+
router.use('*', authMiddleware);
|
|
9
|
+
const CreateDeploymentSchema = z.object({
|
|
10
|
+
promptId: z.string(),
|
|
11
|
+
name: z.string().min(1),
|
|
12
|
+
variants: z.array(z.object({
|
|
13
|
+
versionId: z.string(),
|
|
14
|
+
weight: z.number().int().min(0).max(100),
|
|
15
|
+
isControl: z.boolean().default(false),
|
|
16
|
+
})),
|
|
17
|
+
});
|
|
18
|
+
router.post('/', zValidator('json', CreateDeploymentSchema), async (c) => {
|
|
19
|
+
const projectId = getProjectId(c);
|
|
20
|
+
const body = c.req.valid('json');
|
|
21
|
+
const deployment = await deploymentService.createDeployment(projectId, body.promptId, body.name, body.variants);
|
|
22
|
+
return c.json(deployment, 201);
|
|
23
|
+
});
|
|
24
|
+
router.get('/', async (c) => {
|
|
25
|
+
const projectId = getProjectId(c);
|
|
26
|
+
const promptId = c.req.query('promptId');
|
|
27
|
+
const deployments = await deploymentService.listDeployments(projectId, promptId);
|
|
28
|
+
return c.json({ data: deployments });
|
|
29
|
+
});
|
|
30
|
+
router.get('/:id/resolve', async (c) => {
|
|
31
|
+
const projectId = getProjectId(c);
|
|
32
|
+
const id = c.req.param('id');
|
|
33
|
+
const sessionId = c.req.query('sessionId');
|
|
34
|
+
const versionId = await deploymentService.resolveVersion(projectId, id, sessionId ?? undefined);
|
|
35
|
+
return c.json({ versionId, sessionId });
|
|
36
|
+
});
|
|
37
|
+
const UpdateDeploymentSchema = z.object({
|
|
38
|
+
status: z.enum(['active', 'paused', 'archived']),
|
|
39
|
+
});
|
|
40
|
+
router.put('/:id', zValidator('json', UpdateDeploymentSchema), async (c) => {
|
|
41
|
+
const projectId = getProjectId(c);
|
|
42
|
+
const id = c.req.param('id');
|
|
43
|
+
const body = c.req.valid('json');
|
|
44
|
+
const deployment = await deploymentService.updateStatus(projectId, id, body.status);
|
|
45
|
+
return c.json(deployment);
|
|
46
|
+
});
|
|
47
|
+
export { router as deploymentRoutes };
|
|
48
|
+
//# sourceMappingURL=deployments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployments.js","sourceRoot":"","sources":["../../../src/api/routes/deployments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../../src/api/routes/docs.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,QAAA,MAAM,MAAM,4EAAa,CAAC;AA8E1B,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { Hono } from 'hono';
|
|
5
|
+
const router = new Hono();
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
/**
|
|
8
|
+
* Locate the OpenAPI spec. We support several layouts:
|
|
9
|
+
* - dev: packages/server/src/api/routes/ → ../../../../../docs/api/openapi.yaml
|
|
10
|
+
* - dist: packages/server/dist/api/routes/ → ../../../../../docs/api/openapi.yaml
|
|
11
|
+
* - docker: /app/openapi.yaml (copied at build time)
|
|
12
|
+
* - explicit: $OPENAPI_SPEC_PATH
|
|
13
|
+
*/
|
|
14
|
+
const candidatePaths = [
|
|
15
|
+
...(process.env.OPENAPI_SPEC_PATH ? [process.env.OPENAPI_SPEC_PATH] : []),
|
|
16
|
+
resolve(__dirname, '../../../../../docs/api/openapi.yaml'),
|
|
17
|
+
resolve(process.cwd(), 'docs/api/openapi.yaml'),
|
|
18
|
+
resolve(process.cwd(), 'openapi.yaml'),
|
|
19
|
+
];
|
|
20
|
+
let cachedSpec = null;
|
|
21
|
+
async function loadSpec() {
|
|
22
|
+
if (cachedSpec)
|
|
23
|
+
return cachedSpec;
|
|
24
|
+
for (const p of candidatePaths) {
|
|
25
|
+
try {
|
|
26
|
+
await stat(p);
|
|
27
|
+
cachedSpec = await readFile(p, 'utf8');
|
|
28
|
+
return cachedSpec;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// try next candidate
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
// Where Swagger UI assets are loaded from. Defaults to the public CDN; override
|
|
37
|
+
// via SWAGGER_UI_BASE_URL to point at a vendored copy for airgapped installs.
|
|
38
|
+
const SWAGGER_UI_BASE = (process.env.SWAGGER_UI_BASE_URL ?? 'https://unpkg.com/swagger-ui-dist@5').replace(/\/$/, '');
|
|
39
|
+
router.get('/', async (c) => {
|
|
40
|
+
const spec = await loadSpec();
|
|
41
|
+
if (!spec) {
|
|
42
|
+
return c.json({ error: 'OpenAPI spec not found' }, 404);
|
|
43
|
+
}
|
|
44
|
+
const html = `<!DOCTYPE html>
|
|
45
|
+
<html>
|
|
46
|
+
<head>
|
|
47
|
+
<title>PVC API Documentation</title>
|
|
48
|
+
<meta charset="utf-8" />
|
|
49
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
50
|
+
<link rel="stylesheet" type="text/css" href="${SWAGGER_UI_BASE}/swagger-ui.css" />
|
|
51
|
+
</head>
|
|
52
|
+
<body>
|
|
53
|
+
<div id="swagger-ui"></div>
|
|
54
|
+
<script src="${SWAGGER_UI_BASE}/swagger-ui-bundle.js"></script>
|
|
55
|
+
<script>
|
|
56
|
+
window.onload = function () {
|
|
57
|
+
SwaggerUIBundle({
|
|
58
|
+
url: 'openapi.yaml',
|
|
59
|
+
dom_id: '#swagger-ui',
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
</script>
|
|
63
|
+
</body>
|
|
64
|
+
</html>`;
|
|
65
|
+
return c.html(html);
|
|
66
|
+
});
|
|
67
|
+
router.get('/openapi.yaml', async (c) => {
|
|
68
|
+
const spec = await loadSpec();
|
|
69
|
+
if (!spec) {
|
|
70
|
+
return c.json({ error: 'OpenAPI spec not found' }, 404);
|
|
71
|
+
}
|
|
72
|
+
return c.text(spec, 200, { 'Content-Type': 'text/yaml' });
|
|
73
|
+
});
|
|
74
|
+
export { router as docsRoutes };
|
|
75
|
+
//# sourceMappingURL=docs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../../../src/api/routes/docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;AAE1B,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D;;;;;;GAMG;AACH,MAAM,cAAc,GAAa;IAC/B,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,OAAO,CAAC,SAAS,EAAE,sCAAsC,CAAC;IAC1D,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,uBAAuB,CAAC;IAC/C,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC;CACvC,CAAC;AAEF,IAAI,UAAU,GAAkB,IAAI,CAAC;AACrC,KAAK,UAAU,QAAQ;IACrB,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;YACd,UAAU,GAAG,MAAM,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;YACvC,OAAO,UAAU,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,qBAAqB;QACvB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,gFAAgF;AAChF,8EAA8E;AAC9E,MAAM,eAAe,GAAG,CACtB,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,qCAAqC,CACzE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAErB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC1B,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC9B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,EAAE,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,IAAI,GAAG;;;;;;mDAMoC,eAAe;;;;mBAI/C,eAAe;;;;;;;;;;QAU1B,CAAC;IAEP,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACtC,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC9B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,EAAE,GAAG,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;AAC5D,CAAC,CAAC,CAAC;AAEH,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluations.d.ts","sourceRoot":"","sources":["../../../src/api/routes/evaluations.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAO5B,QAAA,MAAM,MAAM,4EAAa,CAAC;AAgE1B,OAAO,EAAE,MAAM,IAAI,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { zValidator } from '@hono/zod-validator';
|
|
2
|
+
import { EvalStatusSchema } from '@reaatech/prompt-version-control-shared';
|
|
3
|
+
import { Hono } from 'hono';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { AppError } from '../../errors.js';
|
|
6
|
+
import { authMiddleware } from '../../middleware/auth.js';
|
|
7
|
+
import { evalService } from '../../services/eval.service.js';
|
|
8
|
+
import { getProjectId } from '../../utils/context.js';
|
|
9
|
+
const router = new Hono();
|
|
10
|
+
// Webhook is public (HMAC-authenticated). Mount BEFORE the auth middleware.
|
|
11
|
+
const EvalWebhookSchema = z.object({
|
|
12
|
+
harnessId: z.string().optional(),
|
|
13
|
+
status: EvalStatusSchema,
|
|
14
|
+
score: z.number().optional(),
|
|
15
|
+
metrics: z.record(z.unknown()).optional(),
|
|
16
|
+
});
|
|
17
|
+
router.post('/webhook', async (c) => {
|
|
18
|
+
const evaluationId = c.req.query('evaluationId');
|
|
19
|
+
if (!evaluationId) {
|
|
20
|
+
throw new AppError('MISSING_EVALUATION_ID', 400, 'evaluationId query parameter is required');
|
|
21
|
+
}
|
|
22
|
+
const rawBody = await c.req.text();
|
|
23
|
+
let parsed;
|
|
24
|
+
try {
|
|
25
|
+
parsed = JSON.parse(rawBody);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
throw new AppError('INVALID_JSON', 400, 'Invalid JSON body');
|
|
29
|
+
}
|
|
30
|
+
const body = EvalWebhookSchema.parse(parsed);
|
|
31
|
+
const signature = c.req.header('x-webhook-signature') ?? c.req.header('x-hub-signature-256') ?? undefined;
|
|
32
|
+
const eval_ = await evalService.receiveWebhook(evaluationId, rawBody, signature, {
|
|
33
|
+
status: body.status,
|
|
34
|
+
score: body.score,
|
|
35
|
+
metrics: body.metrics,
|
|
36
|
+
});
|
|
37
|
+
return c.json(eval_);
|
|
38
|
+
});
|
|
39
|
+
router.use('*', authMiddleware);
|
|
40
|
+
const TriggerEvalSchema = z.object({
|
|
41
|
+
versionId: z.string(),
|
|
42
|
+
harnessId: z.string().default('default'),
|
|
43
|
+
});
|
|
44
|
+
router.post('/trigger', zValidator('json', TriggerEvalSchema), async (c) => {
|
|
45
|
+
const projectId = getProjectId(c);
|
|
46
|
+
const body = c.req.valid('json');
|
|
47
|
+
const eval_ = await evalService.trigger(projectId, body.versionId, body.harnessId);
|
|
48
|
+
return c.json(eval_, 201);
|
|
49
|
+
});
|
|
50
|
+
router.get('/versions/:versionId', async (c) => {
|
|
51
|
+
const projectId = getProjectId(c);
|
|
52
|
+
const versionId = c.req.param('versionId');
|
|
53
|
+
const evals = await evalService.listByVersion(projectId, versionId);
|
|
54
|
+
return c.json({ data: evals });
|
|
55
|
+
});
|
|
56
|
+
router.get('/versions/:versionId/gate', async (c) => {
|
|
57
|
+
const projectId = getProjectId(c);
|
|
58
|
+
const versionId = c.req.param('versionId');
|
|
59
|
+
const status = await evalService.getPromotionGateStatus(projectId, versionId);
|
|
60
|
+
return c.json(status);
|
|
61
|
+
});
|
|
62
|
+
export { router as evaluationRoutes };
|
|
63
|
+
//# sourceMappingURL=evaluations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluations.js","sourceRoot":"","sources":["../../../src/api/routes/evaluations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/api/routes/metrics.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,QAAA,MAAM,MAAM,4EAAa,CAAC;AAmC1B,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { zValidator } from '@hono/zod-validator';
|
|
2
|
+
import { IngestMetricSchema } from '@reaatech/prompt-version-control-shared';
|
|
3
|
+
import { Hono } from 'hono';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { authMiddleware } from '../../middleware/auth.js';
|
|
6
|
+
import { metricService } from '../../services/metric.service.js';
|
|
7
|
+
import { getProjectId } from '../../utils/context.js';
|
|
8
|
+
const router = new Hono();
|
|
9
|
+
router.use('*', authMiddleware);
|
|
10
|
+
const IngestMetricsSchema = z.object({
|
|
11
|
+
metrics: z.array(IngestMetricSchema),
|
|
12
|
+
});
|
|
13
|
+
router.post('/ingest', zValidator('json', IngestMetricsSchema), async (c) => {
|
|
14
|
+
const projectId = getProjectId(c);
|
|
15
|
+
const body = c.req.valid('json');
|
|
16
|
+
const result = await metricService.ingest(projectId, body.metrics);
|
|
17
|
+
return c.json(result, 201);
|
|
18
|
+
});
|
|
19
|
+
router.get('/versions/:versionId', async (c) => {
|
|
20
|
+
const projectId = getProjectId(c);
|
|
21
|
+
const versionId = c.req.param('versionId');
|
|
22
|
+
const hours = c.req.query('hours');
|
|
23
|
+
const metrics = await metricService.getVersionMetrics(projectId, versionId, {
|
|
24
|
+
hours: hours ? Number(hours) : undefined,
|
|
25
|
+
});
|
|
26
|
+
return c.json({ data: metrics });
|
|
27
|
+
});
|
|
28
|
+
router.get('/prompts/:promptId', async (c) => {
|
|
29
|
+
const projectId = getProjectId(c);
|
|
30
|
+
const promptId = c.req.param('promptId');
|
|
31
|
+
const hours = c.req.query('hours');
|
|
32
|
+
const metrics = await metricService.getPromptMetrics(projectId, promptId, {
|
|
33
|
+
hours: hours ? Number(hours) : undefined,
|
|
34
|
+
});
|
|
35
|
+
return c.json({ data: metrics });
|
|
36
|
+
});
|
|
37
|
+
export { router as metricRoutes };
|
|
38
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../src/api/routes/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;AAE1B,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;AAEhC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC1E,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACnE,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC7C,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE;QAC1E,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;KACzC,CAAC,CAAC;IACH,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AACnC,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,GAAG,CAAC,oBAAoB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC3C,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,gBAAgB,CAAC,SAAS,EAAE,QAAQ,EAAE;QACxE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;KACzC,CAAC,CAAC;IACH,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AACnC,CAAC,CAAC,CAAC;AAEH,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promotions.d.ts","sourceRoot":"","sources":["../../../src/api/routes/promotions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAU5B,QAAA,MAAM,MAAM,4EAAa,CAAC;AAqG1B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,CAAC"}
|