Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
798c232
feat(backend): migrate to Deno with auth security hardening and Docke…
Adjanour May 10, 2026
09f0208
fix(frontend): point TanStack Router at apps/frontend/src/routes
Adjanour May 10, 2026
e3bc8ec
refactor(frontend): adopt Vite 8 oxc, native tsconfig paths, set root
Adjanour May 10, 2026
06a5d78
chore(infra): restore Deno workspace, add frontend Docker/Caddy, fix …
Adjanour May 10, 2026
eed9d5a
docs: update workspace, deployment, and readme to reflect current arc…
Adjanour May 10, 2026
3d7e46b
chore(scripts): fix new-module.sh structure, update pnpm workspace an…
Adjanour May 10, 2026
fe1f2e0
ci: update GitHub Actions for workspace + frontend Docker deployment
Adjanour May 10, 2026
12e3a17
docs: add GitHub pull request template
Adjanour May 10, 2026
c0acfd0
docs: strip example text from PR template
Adjanour May 11, 2026
8e39d02
chore(deps): bump @std/testing to 1.0.19
Adjanour Aug 3, 2026
3e043e4
fix(infra): add postgres and redis services to dev docker-compose.yml
Adjanour Aug 3, 2026
03343b2
feat(jobs): implement real email job, drop cleanup/sync stubs
Adjanour Aug 3, 2026
354e097
chore: normalize deno.json formatting repo-wide
Adjanour Aug 3, 2026
b632000
ci: add frontend checks and deno fmt to CI
Adjanour Aug 3, 2026
7d7d340
test(db): add schema tests for packages/db, fix stale UserRole type
Adjanour Aug 3, 2026
ce622de
test(frontend): add Deno-native test setup with one component and one…
Adjanour Aug 3, 2026
61beda7
docs: fill remaining doc gaps
Adjanour Aug 3, 2026
3a34473
fix: resolve 12 pre-existing require-await lint errors
Adjanour Aug 3, 2026
1d18abe
fix(auth): disable better-auth rate limiting in test environment
Adjanour Aug 3, 2026
710b8df
fix(ci): isolate frontend tests from backend and bump Deno for jsdom …
Adjanour Aug 3, 2026
232c93f
docs: document the CI rate-limit and jsdom/Deno-version bugs
Adjanour Aug 3, 2026
71dea7e
fix(deploy): run migrations from a deno image, not the compiled backe…
Adjanour Aug 3, 2026
60b7c4b
fix(db): map legacy 'user' role to 'buyer' in the enum migration
Adjanour Aug 3, 2026
0baec47
fix(docker): make frontend image installs reproducible
Adjanour Aug 3, 2026
545f4c7
docs: fix stale port and file-layout references
Adjanour Aug 3, 2026
1d54563
fix(scripts): use portable grep for Deno version detection
Adjanour Aug 3, 2026
af21060
ci: run backend and frontend checks as parallel jobs
Adjanour Aug 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,28 @@
node_modules/
**/node_modules/

# Build
# Test files (not needed at runtime)
**/__tests__/
**/*.test.ts

# Build artifacts
dist/
**/dist/

# Git
# Version control
.git/
.gitignore

# IDE
.vscode/
.idea/

# Misc
*.md
# Environment files
.env
.env.*
!.env.example

# Documentation & scripts
*.md
docs/
scripts/
24 changes: 24 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
## Summary

## Motivation

## Changes Made

## Testing Instructions

## Screenshots or Evidence

## Pre-Submission Checklist

- [ ] All tests pass — `deno test -A`
- [ ] No type errors — `deno check`
- [ ] No lint warnings — `deno lint`
- [ ] Tests added or updated for new functionality
- [ ] Branch is rebased on latest `dev`
- [ ] Commit history tells a legible story

## Technical Decisions

## Related Work

## Reviewer Notes
70 changes: 53 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
branches: [master]

jobs:
check:
backend:
runs-on: ubuntu-latest

services:
Expand Down Expand Up @@ -38,39 +38,75 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4
- uses: denoland/setup-deno@v2
with:
version: 9.15.0
# 2.9.0, not 2.7.14 (what the Dockerfiles pin) — the Node-compat
# layer needed for jsdom's undici dependency to work isn't present
# until 2.8.0. Test-tooling only; production images are unaffected
# since they never run `deno test`.
deno-version: "2.9.0"

- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Cache dependencies
run: deno cache apps/backend/src/index.ts apps/backend/src/jobs/worker.ts

- name: Build packages
run: pnpm build:packages
- name: Format check
run: deno fmt --check

- name: Lint
run: pnpm lint
# Excludes apps/frontend — Biome is the linter of record for it,
# checked in the frontend job. Avoids double-linting the same files
# with two different rulesets.
run: deno lint --ignore=apps/frontend

- name: Type check
run: pnpm typecheck
run: deno check apps/backend/src/index.ts

- name: Run migrations
run: pnpm --filter @repo/db db:push:ci
run: deno run --allow-env --allow-net --allow-read --allow-sys apps/backend/src/db/migrate.ts
env:
DATABASE_URL: postgres://test:test@localhost:5432/test

- name: Test
run: pnpm test
# Excludes apps/frontend deliberately — its jsdom-based tests run in
# the frontend job, in a separate process. A frontend DOM-testing
# crash previously took down unrelated backend test results by
# corrupting the shared fetch/undici runtime when run in the same
# `deno test` invocation.
run: deno test -A --ignore=apps/frontend
env:
NODE_ENV: test
DATABASE_URL: postgres://test:test@localhost:5432/test
REDIS_URL: redis://localhost:6379
BETTER_AUTH_SECRET: test-secret-for-ci-at-least-32-chars
BETTER_AUTH_URL: http://localhost:9999
SERVER_URL: http://localhost:9999
FRONTEND_URL: http://localhost:5173
FRONTEND_URL: http://localhost:3000

frontend:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: denoland/setup-deno@v2
with:
deno-version: "2.9.0"

- name: Install frontend dependencies
working-directory: apps/frontend
run: deno install

- name: Frontend lint
run: deno run -A npm:@biomejs/biome@2.3.7 ci apps/frontend

- name: Frontend type check
working-directory: apps/frontend
run: deno task typecheck

- name: Frontend build
working-directory: apps/frontend
run: deno task build

- name: Frontend test
working-directory: apps/frontend
run: deno task test
84 changes: 50 additions & 34 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,17 @@ on:

env:
REGISTRY: ghcr.io
IMAGE_NAME: orctatech-engineering-team/orcta-backend
BACKEND_IMAGE: orctatech-engineering-team/orcta-backend
FRONTEND_IMAGE: orctatech-engineering-team/orcta-frontend

jobs:
build-and-push:
name: Build & push Docker image
build-backend:
name: Build & push backend image
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

outputs:
image_tag: ${{ steps.meta.outputs.version }}

steps:
- uses: actions/checkout@v4

Expand All @@ -33,7 +31,7 @@ jobs:
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
images: ${{ env.REGISTRY }}/${{ env.BACKEND_IMAGE }}
tags: |
type=sha,prefix=,format=short
type=raw,value=latest
Expand All @@ -49,10 +47,45 @@ jobs:
build-args: |
SERVICE_VERSION=${{ github.sha }}

build-frontend:
name: Build & push frontend image
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- uses: actions/checkout@v4

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract image metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.FRONTEND_IMAGE }}
tags: |
type=sha,prefix=,format=short
type=raw,value=latest

- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
file: apps/frontend/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

deploy:
name: Deploy to VPS
runs-on: ubuntu-latest
needs: build-and-push
needs: [build-backend, build-frontend]
environment: production

steps:
Expand All @@ -65,25 +98,15 @@ jobs:
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
script: |
# Fail fast:
# -e → exit on error
# -u → error on undefined variables
# -o pipefail → fail if any command in a pipeline fails
set -euo pipefail

# Static deployment configuration
REPO_NAME="orcta-stack"
APP_DIR="/srv/apps/$REPO_NAME"

# Branch that triggered the workflow (master in your case)
BRANCH="${{ github.ref_name }}"

# Ensure application directory exists (idempotent)
mkdir -p "$APP_DIR"
cd "$APP_DIR"

# Sync repository state
# Clone only once; subsequent deploys pull latest changes
if [ ! -d ".git" ]; then
echo "Cloning repository..."
git clone git@github.com:Orctatech-Engineering-Team/$REPO_NAME.git .
Expand All @@ -94,35 +117,28 @@ jobs:
git pull origin "$BRANCH"
fi

# Hard stop if production environment file is missing
# Prevents accidental boot with empty credentials/secrets
if [ ! -f ".env.production" ]; then
echo "Error: .env.production file not found."
exit 1
fi

# Authenticate with GitHub Container Registry (GHCR)
# Token is piped via stdin to avoid shell history leakage
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin

# Pull latest backend image built by CI
# Pull latest images built by CI
docker pull ghcr.io/orctatech-engineering-team/orcta-backend:latest
docker pull ghcr.io/orctatech-engineering-team/orcta-frontend:latest

# Start infrastructure dependencies first
# --env-file ensures Compose-time variable interpolation works
# Start infrastructure dependencies
IMAGE_TAG=latest docker compose --env-file .env.production -f docker-compose.prod.yml up -d db redis

# Show container states (useful for debugging in CI logs)
docker compose --env-file .env.production -f docker-compose.prod.yml ps

# Run database migrations (deno image with the repo checkout
# mounted — the compiled backend image has no deno executable
# or source tree to run migrate.ts from)
IMAGE_TAG=latest docker compose --env-file .env.production -f docker-compose.prod.yml run --rm migrate

# Run database migrations using the NEW backend image
# --rm prevents orphaned containers
IMAGE_TAG=latest docker compose --env-file .env.production -f docker-compose.prod.yml run --rm backend node src/db/migrate.js

# Update backend container
# Only backend is recreated → DB/Redis remain untouched
IMAGE_TAG=latest docker compose --env-file .env.production -f docker-compose.prod.yml up -d backend
# Recreate backend and frontend
IMAGE_TAG=latest docker compose --env-file .env.production -f docker-compose.prod.yml up -d backend frontend

# Remove dangling/unused images to control disk usage
docker image prune -f
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ dist/
.tsbuildinfo
tsconfig.tsbuildinfo

# pnpm (migrated to Deno)
pnpm-lock.yaml

# Environment files
.env
.env.local
.env.*.local
.env.production

# IDE
# Ignore personal VS Code files; track shared workspace config.
Expand All @@ -35,4 +39,7 @@ coverage/

# Misc
.cache/
.tanstack/
.tanstack/

# Generated
**/routeTree.gen.ts
30 changes: 16 additions & 14 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
{
// Extensions recommended for everyone working in this repo.
// VS Code will prompt teammates to install these when they open the workspace.
"recommendations": [
// Biome — formatter, linter, import sorter. Replaces Prettier + ESLint.
"biomejs.biome",
// TanStack Router — file-based route generation awareness
"tanstack.router-vscode-plugin",
// Tailwind CSS IntelliSense — autocomplete for utility classes
"bradlc.vscode-tailwindcss",
// Prisma / Drizzle don't have great tooling yet, but these help with SQL
"inferrinizzard.prettier-sql-vscode",
// Dot-env syntax highlighting
"mikestead.dotenv"
]
// Extensions recommended for everyone working in this repo.
// VS Code will prompt teammates to install these when they open the workspace.
"recommendations": [
// Deno — runtime, language server, and type support for backend files.
"denoland.vscode-deno",
// Biome — formatter, linter, import sorter. Replaces Prettier + ESLint.
"biomejs.biome",
// TanStack Router — file-based route generation awareness
"tanstack.router-vscode-plugin",
// Tailwind CSS IntelliSense — autocomplete for utility classes
"bradlc.vscode-tailwindcss",
// Prisma / Drizzle don't have great tooling yet, but these help with SQL
"inferrinizzard.prettier-sql-vscode",
// Dot-env syntax highlighting
"mikestead.dotenv"
]
}
Loading
Loading