Skip to content

Commit cca8a9d

Browse files
authored
feat: health check and stats endpoints (#290)
1 parent 57186b6 commit cca8a9d

22 files changed

+447
-59
lines changed

README.md

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -138,44 +138,45 @@ pnpm dev
138138

139139
## Environment Variables 🔐
140140

141-
| Variable | Description | Required | Example |
142-
| ----------------------------------------- | --------------------------------------------------------- | ------------------------ | ----------------------------------------------------------- |
143-
| `POSTGRES_URL` | PostgreSQL connection URL | To use external database | `postgres://user:pass@localhost:5432/db` |
144-
| `EMAIL_FROM` | Sender email address | For Email | `"Kan <hello@mail.kan.bn>"` |
145-
| `SMTP_HOST` | SMTP server hostname | For Email | `smtp.resend.com` |
146-
| `SMTP_PORT` | SMTP server port | For Email | `465` |
147-
| `SMTP_USER` | SMTP username/email | No | `resend` |
148-
| `SMTP_PASSWORD` | SMTP password/token | No | `re_xxxx` |
149-
| `SMTP_SECURE` | Use secure SMTP connection (defaults to true if not set) | For Email | `true` |
150-
| `SMTP_REJECT_UNAUTHORIZED` | Reject invalid certificates (defaults to true if not set) | For Email | `false` |
151-
| `NEXT_PUBLIC_DISABLE_EMAIL` | To disable all email features | For Email | `true` |
152-
| `NEXT_PUBLIC_BASE_URL` | Base URL of your installation | Yes | `http://localhost:3000` |
153-
| `BETTER_AUTH_ALLOWED_DOMAINS` | Comma-separated list of allowed domains for OIDC logins | For OIDC/Social login | `example.com,subsidiary.com` |
154-
| `BETTER_AUTH_SECRET` | Auth encryption secret | Yes | Random 32+ char string |
155-
| `BETTER_AUTH_TRUSTED_ORIGINS` | Allowed callback origins | No | `http://localhost:3000,http://localhost:3001` |
156-
| `GOOGLE_CLIENT_ID` | Google OAuth client ID | For Google login | `xxx.apps.googleusercontent.com` |
157-
| `GOOGLE_CLIENT_SECRET` | Google OAuth client secret | For Google login | `xxx` |
158-
| `DISCORD_CLIENT_ID` | Discord OAuth client ID | For Discord login | `xxx` |
159-
| `DISCORD_CLIENT_SECRET` | Discord OAuth client secret | For Discord login | `xxx` |
160-
| `GITHUB_CLIENT_ID` | GitHub OAuth client ID | For GitHub login | `xxx` |
161-
| `GITHUB_CLIENT_SECRET` | GitHub OAuth client secret | For GitHub login | `xxx` |
162-
| `OIDC_CLIENT_ID` | Generic OIDC client ID | For OIDC login | `xxx` |
163-
| `OIDC_CLIENT_SECRET` | Generic OIDC client secret | For OIDC login | `xxx` |
164-
| `OIDC_DISCOVERY_URL` | OIDC discovery URL | For OIDC login | `https://auth.example.com/.well-known/openid-configuration` |
165-
| `TRELLO_APP_API_KEY` | Trello app API key | For Trello import | `xxx` |
166-
| `TRELLO_APP_API_SECRET` | Trello app API secret | For Trello import | `xxx` |
167-
| `S3_REGION` | S3 storage region | For file uploads | `WEUR` |
168-
| `S3_ENDPOINT` | S3 endpoint URL | For file uploads | `https://xxx.r2.cloudflarestorage.com` |
141+
| Variable | Description | Required | Example |
142+
| ----------------------------------------- | --------------------------------------------------------- | ------------------------------------- | ----------------------------------------------------------- |
143+
| `POSTGRES_URL` | PostgreSQL connection URL | To use external database | `postgres://user:pass@localhost:5432/db` |
144+
| `EMAIL_FROM` | Sender email address | For Email | `"Kan <hello@mail.kan.bn>"` |
145+
| `SMTP_HOST` | SMTP server hostname | For Email | `smtp.resend.com` |
146+
| `SMTP_PORT` | SMTP server port | For Email | `465` |
147+
| `SMTP_USER` | SMTP username/email | No | `resend` |
148+
| `SMTP_PASSWORD` | SMTP password/token | No | `re_xxxx` |
149+
| `SMTP_SECURE` | Use secure SMTP connection (defaults to true if not set) | For Email | `true` |
150+
| `SMTP_REJECT_UNAUTHORIZED` | Reject invalid certificates (defaults to true if not set) | For Email | `false` |
151+
| `NEXT_PUBLIC_DISABLE_EMAIL` | To disable all email features | For Email | `true` |
152+
| `NEXT_PUBLIC_BASE_URL` | Base URL of your installation | Yes | `http://localhost:3000` |
153+
| `BETTER_AUTH_ALLOWED_DOMAINS` | Comma-separated list of allowed domains for OIDC logins | For OIDC/Social login | `example.com,subsidiary.com` |
154+
| `BETTER_AUTH_SECRET` | Auth encryption secret | Yes | Random 32+ char string |
155+
| `BETTER_AUTH_TRUSTED_ORIGINS` | Allowed callback origins | No | `http://localhost:3000,http://localhost:3001` |
156+
| `GOOGLE_CLIENT_ID` | Google OAuth client ID | For Google login | `xxx.apps.googleusercontent.com` |
157+
| `GOOGLE_CLIENT_SECRET` | Google OAuth client secret | For Google login | `xxx` |
158+
| `DISCORD_CLIENT_ID` | Discord OAuth client ID | For Discord login | `xxx` |
159+
| `DISCORD_CLIENT_SECRET` | Discord OAuth client secret | For Discord login | `xxx` |
160+
| `GITHUB_CLIENT_ID` | GitHub OAuth client ID | For GitHub login | `xxx` |
161+
| `GITHUB_CLIENT_SECRET` | GitHub OAuth client secret | For GitHub login | `xxx` |
162+
| `OIDC_CLIENT_ID` | Generic OIDC client ID | For OIDC login | `xxx` |
163+
| `OIDC_CLIENT_SECRET` | Generic OIDC client secret | For OIDC login | `xxx` |
164+
| `OIDC_DISCOVERY_URL` | OIDC discovery URL | For OIDC login | `https://auth.example.com/.well-known/openid-configuration` |
165+
| `TRELLO_APP_API_KEY` | Trello app API key | For Trello import | `xxx` |
166+
| `TRELLO_APP_API_SECRET` | Trello app API secret | For Trello import | `xxx` |
167+
| `S3_REGION` | S3 storage region | For file uploads | `WEUR` |
168+
| `S3_ENDPOINT` | S3 endpoint URL | For file uploads | `https://xxx.r2.cloudflarestorage.com` |
169169
| `S3_ACCESS_KEY_ID` | S3 access key | For file uploads (optional with IRSA) | `xxx` |
170170
| `S3_SECRET_ACCESS_KEY` | S3 secret key | For file uploads (optional with IRSA) | `xxx` |
171-
| `S3_FORCE_PATH_STYLE` | Use path-style URLs for S3 | For file uploads | `true` |
172-
| `NEXT_PUBLIC_STORAGE_URL` | Storage service URL | For file uploads | `https://storage.kanbn.com` |
173-
| `NEXT_PUBLIC_STORAGE_DOMAIN` | Storage domain name | For file uploads | `kanbn.com` |
174-
| `NEXT_PUBLIC_AVATAR_BUCKET_NAME` | S3 bucket name for avatars | For file uploads | `avatars` |
175-
| `NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME` | S3 bucket name for attachments | For file uploads | `attachments` |
176-
| `NEXT_PUBLIC_ALLOW_CREDENTIALS` | Allow email & password login | For authentication | `true` |
177-
| `NEXT_PUBLIC_DISABLE_SIGN_UP` | Disable sign up | For authentication | `false` |
178-
| `NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY` | Hide “Powered by kan.bn” on public boards (self-host) | For white labelling | `true` |
171+
| `S3_FORCE_PATH_STYLE` | Use path-style URLs for S3 | For file uploads | `true` |
172+
| `NEXT_PUBLIC_STORAGE_URL` | Storage service URL | For file uploads | `https://storage.kanbn.com` |
173+
| `NEXT_PUBLIC_STORAGE_DOMAIN` | Storage domain name | For file uploads | `kanbn.com` |
174+
| `NEXT_PUBLIC_AVATAR_BUCKET_NAME` | S3 bucket name for avatars | For file uploads | `avatars` |
175+
| `NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME` | S3 bucket name for attachments | For file uploads | `attachments` |
176+
| `NEXT_PUBLIC_ALLOW_CREDENTIALS` | Allow email & password login | For authentication | `true` |
177+
| `NEXT_PUBLIC_DISABLE_SIGN_UP` | Disable sign up | For authentication | `false` |
178+
| `NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY` | Hide “Powered by kan.bn” on public boards (self-host) | For white labelling | `true` |
179+
| `KAN_ADMIN_API_KEY` | Admin API key for stats and admin endpoints | For admin/monitoring | `your-secret-admin-key` |
179180

180181
See `.env.example` for a complete list of supported environment variables.
181182

apps/web/src/env.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export const env = createEnv({
1414
* This way you can ensure the app isn't built with invalid env vars.
1515
*/
1616
server: {
17+
KAN_ADMIN_API_KEY: z.string().optional(),
1718
BETTER_AUTH_SECRET: z.string(),
1819
BETTER_AUTH_TRUSTED_ORIGINS: z
1920
.string()

cloud/docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ services:
1313
- .env
1414
restart: unless-stopped
1515
environment:
16+
- KAN_ADMIN_API_KEY=${KAN_ADMIN_API_KEY}
1617
- NEXT_PUBLIC_KAN_ENV=${NEXT_PUBLIC_KAN_ENV}
1718
- NEXT_PUBLIC_BASE_URL=${NEXT_PUBLIC_BASE_URL}
1819
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}

docker-compose.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ services:
1818
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
1919
- POSTGRES_URL=${POSTGRES_URL}
2020

21+
# Admin API key (optional)
22+
- KAN_ADMIN_API_KEY=${KAN_ADMIN_API_KEY}
23+
2124
# SMTP (optional)
2225
- SMTP_HOST=${SMTP_HOST}
2326
- SMTP_PORT=${SMTP_PORT}

packages/api/src/openapi.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,15 @@ export const openApiDocument = generateOpenApiDocument(appRouter, {
99
version: "1.0.0",
1010
baseUrl: `${env("NEXT_PUBLIC_BASE_URL")}/api/v1`,
1111
docsUrl: "docs.kan.bn",
12-
tags: ["Auth", "Users", "Boards", "Lists", "Cards", "Labels", "Imports", "Integrations"],
12+
tags: [
13+
"Auth",
14+
"Users",
15+
"Boards",
16+
"Lists",
17+
"Cards",
18+
"Labels",
19+
"Imports",
20+
"Integrations",
21+
"Health",
22+
],
1323
});

packages/api/src/root.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { boardRouter } from "./routers/board";
33
import { cardRouter } from "./routers/card";
44
import { checklistRouter } from "./routers/checklist";
55
import { feedbackRouter } from "./routers/feedback";
6+
import { healthRouter } from "./routers/health";
67
import { importRouter } from "./routers/import";
78
import { integrationRouter } from "./routers/integration";
89
import { labelRouter } from "./routers/label";
@@ -18,6 +19,7 @@ export const appRouter = createTRPCRouter({
1819
card: cardRouter,
1920
checklist: checklistRouter,
2021
feedback: feedbackRouter,
22+
health: healthRouter,
2123
label: labelRouter,
2224
list: listRouter,
2325
member: memberRouter,

0 commit comments

Comments
 (0)