Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
3aeb1cd
first commit
Joshleeopard Oct 27, 2025
6fa2804
CI push
Joshleeopard Oct 27, 2025
c47f809
adding last step
Joshleeopard Oct 27, 2025
e7035e8
first test
Joshleeopard Oct 30, 2025
7a9f120
install dependencies step and run test
Joshleeopard Oct 30, 2025
fc70c91
adding coverage
Joshleeopard Oct 30, 2025
7cecb43
typo fix
Joshleeopard Oct 30, 2025
278ee9e
fix typo again
Joshleeopard Oct 30, 2025
8ba6190
overwrite package
Joshleeopard Oct 30, 2025
af88777
npm install vitest coverage
Joshleeopard Oct 30, 2025
94fc9b9
reinstall vitest
Joshleeopard Oct 30, 2025
5cf1a8f
udpating node to v20
Joshleeopard Oct 30, 2025
38913b7
adding readme badge
Joshleeopard Oct 30, 2025
fc1fb11
badge add
Joshleeopard Oct 30, 2025
2a2b95c
badge at top
Joshleeopard Oct 30, 2025
0c7da18
badge
Joshleeopard Oct 30, 2025
207118f
correctr format
Joshleeopard Oct 30, 2025
f3efcb5
psuh badge
Joshleeopard Oct 30, 2025
2ce9eab
typo
Joshleeopard Oct 30, 2025
7d88f3f
fix
Joshleeopard Oct 30, 2025
98a6185
remove line
Joshleeopard Oct 30, 2025
3150a47
Merge pull request #1 from Joshleeopard/addtests
Joshleeopard Oct 30, 2025
2138744
adding formatting from prettier
Joshleeopard Nov 2, 2025
41b2a8f
add style job with format run
Joshleeopard Nov 2, 2025
1566cc5
Merge pull request #2 from Joshleeopard/addtests
Joshleeopard Nov 2, 2025
a3ecb2f
lintignore
Joshleeopard Nov 2, 2025
1702414
revert ignore
Joshleeopard Nov 2, 2025
a8a36fc
npm run lint in ci and add new unused functions
Joshleeopard Nov 2, 2025
a41ff29
remove unused function
Joshleeopard Nov 2, 2025
c75cf9b
Merge pull request #3 from Joshleeopard/addtests
Joshleeopard Nov 2, 2025
c8e19d5
adding security lint
Joshleeopard Nov 2, 2025
e0429eb
Added: style check linting
Joshleeopard Nov 2, 2025
4dde147
Merge pull request #4 from Joshleeopard/addtests
Joshleeopard Nov 2, 2025
87daa66
replaced: crypto.randomBytes instead of crypto.pseudoRandomBytes
Joshleeopard Nov 2, 2025
88b6244
Merge pull request #5 from Joshleeopard/addtests
Joshleeopard Nov 2, 2025
ca0a2b0
adding continuous deployment cd
Joshleeopard Nov 3, 2025
abfc7f1
Merge pull request #6 from Joshleeopard/addtests
Joshleeopard Nov 3, 2025
2f9cddf
trigger cd
Joshleeopard Nov 3, 2025
8e4bd3f
cd wasn't in workflows
Joshleeopard Nov 3, 2025
d81c298
automate the build
Joshleeopard Nov 3, 2025
93022a1
fix credentials
Joshleeopard Nov 3, 2025
93b7641
adding auth list
Joshleeopard Nov 3, 2025
eb560cd
formatting issue
Joshleeopard Nov 3, 2025
114796f
typo: notely-ar-repo
Joshleeopard Nov 3, 2025
0c637d2
Added: Cloud run unauthenticated, heaader change h1
Joshleeopard Nov 4, 2025
29d38e4
Update: run migration before build
Joshleeopard Nov 4, 2025
54a2cb5
typo: db:migrate not migrate
Joshleeopard Nov 4, 2025
81debcf
Added: Tursoauthtoken
Joshleeopard Nov 4, 2025
3f1566b
fixing to solution
Joshleeopard Nov 4, 2025
f986620
updating placeholder values
Joshleeopard Nov 4, 2025
cdc7038
Update: drizzle config
Joshleeopard Nov 4, 2025
e71c2b9
run migration fix
Joshleeopard Nov 4, 2025
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
60 changes: 60 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Purpose
-------
This repo is a small TypeScript Express app ("Notely") used for a CICD course. The goal of this file is to give AI coding assistants the minimum, actionable knowledge they need to be productive here: where to make changes, important conventions, and how to run/build/test the project.

Quick commands
--------------
- Install deps: npm ci
- Build: npm run build (runs npx tsc)
- Dev (build + run): npm run dev (note: no watcher; compiles then runs dist/main.js)
- Run tests: npm run test (vitest)
- DB: drizzle-kit commands in package.json (db:generate, db:migrate, db:studio)
- CI: .github/workflows/ci.yml uses Node 20 and runs `npm ci` then `npm run test -- --coverage`.

High level architecture (what to edit)
-------------------------------------
- Entry: `src/main.ts` — creates the Express app, serves static files and mounts `v1` routes.
- Static site root configured in `src/config.ts` (api.filepathRoot).
- Routes under `/v1` are conditionally registered only when a DB connection exists (see `db` in `src/db/index.ts`).
- API handlers: `src/api/*.ts` (users.ts, notes.ts, middleware.ts, json.ts, auth.ts). Add new handlers here and register them in `src/main.ts`.
- Pattern: pure handler functions like `handlerUsersCreate(req,res)` and protected routes wrapped with `middlewareAuth(handler)` which injects a `User` object.
- DB layer: `src/db/schema.ts` (Drizzle schema) and `src/db/queries/*.ts` (query helpers). Use Drizzle types exported from `schema.ts` (`User`, `Note`).
- Config for migrations: `drizzle.config.ts` points at `./src/db/schema.ts` and outputs migrations to `./src/db/migrations`.

Project-specific conventions and gotchas
--------------------------------------
- ESM + TypeScript: package.json sets `type: "module"`. Source files import other modules using `.js` extensions (for example `import { config } from "./config.js"`) to match the compiled ESM output — preserve this pattern when editing imports.
- Optional DB mode: If `DATABASE_URL` (config.db.url) is not set, the server runs without registering DB-backed CRUD endpoints. This is intentional for local exercises; to enable full behavior set `DATABASE_URL` in `.env`.
- Auth: API key authentication uses the `Authorization` header with the scheme `ApiKey` (see `src/api/auth.ts` and `middlewareAuth` in `src/api/middleware.ts`). When adding protected endpoints, wrap handlers with `middlewareAuth(handler)` and accept a `User` parameter.
- Error/JSON helpers: Use `respondWithJSON` and `respondWithError` in `src/api/json.ts` to standardize responses (these enforce JSON payload shapes).
- UUIDs & hashes: Handlers use `uuid` for IDs and generate API keys in `src/api/users.ts`. There is an inline comment about `crypto.pseudoRandomBytes` — consider switching to `crypto.randomBytes` if updating security code.

Editing patterns / examples
---------------------------
- Add a new protected endpoint:
1. Create handler in `src/api/yourFeature.ts` with signature `(req,res,user)`.
2. Export it and register in `src/main.ts` only under `if (db) { ... }` so it remains conditional.
3. Add DB helpers in `src/db/queries/yourFeature.ts` and reuse types from `src/db/schema.ts`.

- Example: `src/main.ts` registers `v1Router.post("/users", handlerUsersCreate)`; protected routes call `middlewareAuth(handler)` so the handler receives the typed `User` object.

Files to read first
-------------------
- `src/main.ts` — how routes and static assets are wired
- `src/config.ts` — env keys and defaults
- `src/api/*.ts` — handler and middleware patterns
- `src/db/schema.ts` and `src/db/queries/*` — data model and helpers
- `drizzle.config.ts` — migration configuration
- `package.json` and `.github/workflows/ci.yml` — scripts and CI expectations

Testing & CI notes
------------------
- Tests run with `vitest`. CI runs tests with coverage (`npm run test -- --coverage`). If you add tests, follow existing test location conventions (see `src/api/firstest.test.ts`).
- Keep tests fast and avoid reliance on external DB in unit tests; DB-backed integration tests should be clearly separated.

If something is unclear
----------------------
- Ask which environment (local/no-db vs DB) you should target. If you need DB access, request the DATABASE_URL or use a local sqlite/turso dev DB.
- If you want me to add a new endpoint, tell me the shape of requests/responses and whether it needs auth or DB access.

Would you like me to merge this into the repo now or change the tone/level of detail? (I can update examples or add a short checklist for PRs.)
50 changes: 50 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: cd

on:
push:
branches: [main]

jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}

steps:
- name: Check out code
uses: actions/checkout@v4

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 18

- name: Install dependencies
run: npm ci

- name: Build app
run: npm run build

- id: auth
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GCP_CREDENTIALS }}

- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2

- name: Use gcloud CLI
run: gcloud info

- name: Build and push Docker image
run: gcloud builds submit --tag us-central1-docker.pkg.dev/notely-477105/notely-ar-repo/notely-app:latest .

- name: Run migrations
run: npm run db:migrate
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
TURSO_AUTH_TOKEN: ${{ secrets.TURSO_AUTH_TOKEN }}

- name: Deploy to Cloud Run
run: gcloud run deploy notely --image us-central1-docker.pkg.dev/notely-477105/notely-ar-repo/notely-app:latest --region us-central1 --allow-unauthenticated --project notely-477105 --max-instances=4
50 changes: 50 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: ci

on:
pull_request:
branches: [main]

jobs:
tests:
name: Tests
runs-on: ubuntu-latest

steps:
- name: Check out code
uses: actions/checkout@v4

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install Dependencies
run: npm ci

- name: Last Step
run: npm run test -- --coverage

style:
name: Style
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install Dependencies
run: npm ci

- name: format
run: npm run format:check

- name: lint
run: npm run lint

- name: Check linting
run: npm run lint -- --max-warnings=0

2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Create a `.env` file in the root of the project with the following contents:
PORT="8080"
```



Run the server:

```bash
Expand Down
Empty file added dev.db
Empty file.
4 changes: 2 additions & 2 deletions drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { defineConfig } from "drizzle-kit";

import { config } from "./src/config";

export default defineConfig({
Expand All @@ -8,5 +7,6 @@ export default defineConfig({
dialect: "turso",
dbCredentials: {
url: config.db.url || "",
authToken: process.env.TURSO_AUTH_TOKEN || "",
},
});
});
19 changes: 19 additions & 0 deletions eslint.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import js from "@eslint/js";
import globals from "globals";
import tseslint from "typescript-eslint";
import { defineConfig } from "eslint/config";
import pluginSecurity from "eslint-plugin-security";

export default defineConfig([
{
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
plugins: { js },
extends: ["js/recommended"],
},
{
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
languageOptions: { globals: globals.node },
},
tseslint.configs.recommended,
pluginSecurity.configs.recommended,
]);
Loading