Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1ea319e122 | |||
| da913d600f | |||
| ce9fcfb362 | |||
| 59893908e2 | |||
| 2b78fcf731 | |||
| c9e176f08c | |||
| 0cab1522cf | |||
| 2a27e8bee2 | |||
| d6f7ade7bd | |||
| 00dadac0a1 | |||
| 9692476202 |
+43
-3
@@ -25,7 +25,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 22
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
@@ -49,7 +49,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 22
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
@@ -59,7 +59,7 @@ jobs:
|
|||||||
run: pnpm test
|
run: pnpm test
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
name: Build & Push Docker Image
|
name: Build & Push Docker Images
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [lint-typecheck, test]
|
needs: [lint-typecheck, test]
|
||||||
steps:
|
steps:
|
||||||
@@ -91,9 +91,49 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: Dockerfile
|
file: Dockerfile
|
||||||
|
target: runner
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
git.farh.net/groombook/api:${{ steps.version.outputs.tag }}
|
git.farh.net/groombook/api:${{ steps.version.outputs.tag }}
|
||||||
${{ github.ref == 'refs/heads/main' && 'git.farh.net/groombook/api:latest' || '' }}
|
${{ github.ref == 'refs/heads/main' && 'git.farh.net/groombook/api:latest' || '' }}
|
||||||
cache-from: type=registry,ref=git.farh.net/groombook/cache:api
|
cache-from: type=registry,ref=git.farh.net/groombook/cache:api
|
||||||
cache-to: type=registry,ref=git.farh.net/groombook/cache:api,mode=max
|
cache-to: type=registry,ref=git.farh.net/groombook/cache:api,mode=max
|
||||||
|
|
||||||
|
- name: Build and push Migrate image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: Dockerfile
|
||||||
|
target: migrate
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
git.farh.net/groombook/migrate:${{ steps.version.outputs.tag }}
|
||||||
|
${{ github.ref == 'refs/heads/main' && 'git.farh.net/groombook/migrate:latest' || '' }}
|
||||||
|
cache-from: type=registry,ref=git.farh.net/groombook/cache:migrate
|
||||||
|
cache-to: type=registry,ref=git.farh.net/groombook/cache:migrate,mode=max
|
||||||
|
|
||||||
|
- name: Build and push Seed image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: Dockerfile
|
||||||
|
target: seed
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
git.farh.net/groombook/seed:${{ steps.version.outputs.tag }}
|
||||||
|
${{ github.ref == 'refs/heads/main' && 'git.farh.net/groombook/seed:latest' || '' }}
|
||||||
|
cache-from: type=registry,ref=git.farh.net/groombook/cache:seed
|
||||||
|
cache-to: type=registry,ref=git.farh.net/groombook/cache:seed,mode=max
|
||||||
|
|
||||||
|
- name: Build and push Reset image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: Dockerfile
|
||||||
|
target: reset
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
git.farh.net/groombook/reset:${{ steps.version.outputs.tag }}
|
||||||
|
${{ github.ref == 'refs/heads/main' && 'git.farh.net/groombook/reset:latest' || '' }}
|
||||||
|
cache-from: type=registry,ref=git.farh.net/groombook/cache:reset
|
||||||
|
cache-to: type=registry,ref=git.farh.net/groombook/cache:reset,mode=max
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 22
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
@@ -49,7 +49,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 22
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
@@ -71,7 +71,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 22
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
FROM node:20-alpine AS base
|
FROM node:22-alpine AS base
|
||||||
RUN corepack enable && corepack prepare pnpm@9.15.4 --activate
|
RUN corepack enable && corepack prepare pnpm@9.15.4 --activate
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ RUN pnpm --filter @groombook/types build && \
|
|||||||
pnpm --filter @groombook/api build
|
pnpm --filter @groombook/api build
|
||||||
|
|
||||||
# Runtime
|
# Runtime
|
||||||
FROM node:20-alpine AS runner
|
FROM node:22-alpine AS runner
|
||||||
RUN corepack enable && corepack prepare pnpm@9.15.4 --activate
|
RUN corepack enable && corepack prepare pnpm@9.15.4 --activate
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ GroomBook API is a Hono-based REST service (TypeScript/Node.js) powering the pet
|
|||||||
| TC-API-1.13 | Name fallback — user.name present | Auto-provision where Better-Auth user has name set | Staff name = user.name value from user table |
|
| TC-API-1.13 | Name fallback — user.name present | Auto-provision where Better-Auth user has name set | Staff name = user.name value from user table |
|
||||||
| TC-API-1.14 | Name fallback — no name, email present | Auto-provision where Better-Auth user has name = null, email = "test@example.com" | Staff name = "test" (email prefix before @) |
|
| TC-API-1.14 | Name fallback — no name, email present | Auto-provision where Better-Auth user has name = null, email = "test@example.com" | Staff name = "test" (email prefix before @) |
|
||||||
| TC-API-1.15 | Name fallback — no name, no email | Auto-provision where Better-Auth user has name = null, email = null | Staff name = "Unknown" |
|
| TC-API-1.15 | Name fallback — no name, no email | Auto-provision where Better-Auth user has name = null, email = null | Staff name = "Unknown" |
|
||||||
|
| TC-API-1.16 | OIDC login — Terraform-provisioned user | Initiate OIDC login as any UAT persona (uat-super, uat-groomer, uat-customer, uat-tester), complete authentik callback | 200 OK, session created — no account_not_linked error |
|
||||||
|
|
||||||
### 4.2 Client Management
|
### 4.2 Client Management
|
||||||
|
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ function makeDeleteChainable(): unknown {
|
|||||||
}
|
}
|
||||||
if (prop === "returning") {
|
if (prop === "returning") {
|
||||||
return () => {
|
return () => {
|
||||||
const row = petRows[0];
|
const row = petRows[0]!;
|
||||||
deletedId = row.id as string;
|
deletedId = row.id as string;
|
||||||
return [row];
|
return [row];
|
||||||
};
|
};
|
||||||
@@ -165,10 +165,10 @@ vi.mock("../db", async (importOriginal) => {
|
|||||||
}),
|
}),
|
||||||
pets,
|
pets,
|
||||||
appointments,
|
appointments,
|
||||||
and: db.and,
|
and: vi.fn(),
|
||||||
eq: db.eq,
|
eq: vi.fn(),
|
||||||
exists: db.exists,
|
exists: vi.fn(),
|
||||||
or: db.or,
|
or: vi.fn(),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,11 @@ vi.mock("../db", () => {
|
|||||||
{ get: (t, p) => (p === "_name" ? "impersonationSessions" : { table: "impersonationSessions", column: p }) }
|
{ get: (t, p) => (p === "_name" ? "impersonationSessions" : { table: "impersonationSessions", column: p }) }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const impersonationAuditLogs = new Proxy(
|
||||||
|
{ _name: "impersonationAuditLogs" },
|
||||||
|
{ get: (t, p) => (p === "_name" ? "impersonationAuditLogs" : { table: "impersonationAuditLogs", column: p }) }
|
||||||
|
);
|
||||||
|
|
||||||
const appointments = new Proxy(
|
const appointments = new Proxy(
|
||||||
{ _name: "appointments" },
|
{ _name: "appointments" },
|
||||||
{ get: (t, p) => (p === "_name" ? "appointments" : { table: "appointments", column: p }) }
|
{ get: (t, p) => (p === "_name" ? "appointments" : { table: "appointments", column: p }) }
|
||||||
@@ -99,8 +104,12 @@ vi.mock("../db", () => {
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
insert: () => ({
|
||||||
|
values: () => ({ returning: () => [{}] }),
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
impersonationSessions,
|
impersonationSessions,
|
||||||
|
impersonationAuditLogs,
|
||||||
appointments,
|
appointments,
|
||||||
eq: vi.fn(),
|
eq: vi.fn(),
|
||||||
and: vi.fn(),
|
and: vi.fn(),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
"packageManager": "pnpm@9.15.4",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "tsx watch src/index.ts",
|
"dev": "tsx watch src/index.ts",
|
||||||
"build": "tsc --project .",
|
"build": "tsc --project .",
|
||||||
|
|||||||
Generated
+6
-2
@@ -28,7 +28,7 @@ importers:
|
|||||||
version: 0.7.6(hono@4.12.18)(zod@4.4.3)
|
version: 0.7.6(hono@4.12.18)(zod@4.4.3)
|
||||||
better-auth:
|
better-auth:
|
||||||
specifier: ^1.5.6
|
specifier: ^1.5.6
|
||||||
version: 1.6.10(drizzle-orm@0.38.4(kysely@0.28.17)(postgres@3.4.9))(vitest@3.2.4(@types/node@22.19.18)(tsx@4.21.0))
|
version: 1.6.10(drizzle-kit@0.30.6)(drizzle-orm@0.38.4(kysely@0.28.17)(postgres@3.4.9))(vitest@3.2.4(@types/node@22.19.18)(tsx@4.21.0))
|
||||||
drizzle-orm:
|
drizzle-orm:
|
||||||
specifier: ^0.38.4
|
specifier: ^0.38.4
|
||||||
version: 0.38.4(kysely@0.28.17)(postgres@3.4.9)
|
version: 0.38.4(kysely@0.28.17)(postgres@3.4.9)
|
||||||
@@ -84,6 +84,9 @@ importers:
|
|||||||
|
|
||||||
packages/db:
|
packages/db:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
better-auth:
|
||||||
|
specifier: ^1.5.6
|
||||||
|
version: 1.6.10(drizzle-kit@0.30.6)(drizzle-orm@0.38.4(kysely@0.28.17)(postgres@3.4.9))(vitest@3.2.4(@types/node@22.19.18)(tsx@4.21.0))
|
||||||
drizzle-orm:
|
drizzle-orm:
|
||||||
specifier: ^0.38.4
|
specifier: ^0.38.4
|
||||||
version: 0.38.4(kysely@0.28.17)(postgres@3.4.9)
|
version: 0.38.4(kysely@0.28.17)(postgres@3.4.9)
|
||||||
@@ -3927,7 +3930,7 @@ snapshots:
|
|||||||
|
|
||||||
balanced-match@4.0.4: {}
|
balanced-match@4.0.4: {}
|
||||||
|
|
||||||
better-auth@1.6.10(drizzle-orm@0.38.4(kysely@0.28.17)(postgres@3.4.9))(vitest@3.2.4(@types/node@22.19.18)(tsx@4.21.0)):
|
better-auth@1.6.10(drizzle-kit@0.30.6)(drizzle-orm@0.38.4(kysely@0.28.17)(postgres@3.4.9))(vitest@3.2.4(@types/node@22.19.18)(tsx@4.21.0)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@better-auth/core': 1.6.10(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0)
|
'@better-auth/core': 1.6.10(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0)
|
||||||
'@better-auth/drizzle-adapter': 1.6.10(@better-auth/core@1.6.10(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(drizzle-orm@0.38.4(kysely@0.28.17)(postgres@3.4.9))
|
'@better-auth/drizzle-adapter': 1.6.10(@better-auth/core@1.6.10(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(drizzle-orm@0.38.4(kysely@0.28.17)(postgres@3.4.9))
|
||||||
@@ -3947,6 +3950,7 @@ snapshots:
|
|||||||
nanostores: 1.3.0
|
nanostores: 1.3.0
|
||||||
zod: 4.4.3
|
zod: 4.4.3
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
|
drizzle-kit: 0.30.6
|
||||||
drizzle-orm: 0.38.4(kysely@0.28.17)(postgres@3.4.9)
|
drizzle-orm: 0.38.4(kysely@0.28.17)(postgres@3.4.9)
|
||||||
vitest: 3.2.4(@types/node@22.19.18)(tsx@4.21.0)
|
vitest: 3.2.4(@types/node@22.19.18)(tsx@4.21.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
|||||||
@@ -251,6 +251,10 @@ export async function initAuth(): Promise<void> {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
account: {
|
account: {
|
||||||
|
accountLinking: {
|
||||||
|
enabled: true,
|
||||||
|
trustedProviders: ["authentik"],
|
||||||
|
},
|
||||||
storeStateStrategy: "cookie" as const,
|
storeStateStrategy: "cookie" as const,
|
||||||
},
|
},
|
||||||
emailAndPassword: {
|
emailAndPassword: {
|
||||||
|
|||||||
Reference in New Issue
Block a user