Skip to content

feat: add rest-express-docker-aws-ec2 deployment example#8473

Open
DiluDevX wants to merge 6 commits intoprisma:latestfrom
DiluDevX:add-rest-express-docker-aws-ecs
Open

feat: add rest-express-docker-aws-ec2 deployment example#8473
DiluDevX wants to merge 6 commits intoprisma:latestfrom
DiluDevX:add-rest-express-docker-aws-ecs

Conversation

@DiluDevX
Copy link

@DiluDevX DiluDevX commented Mar 17, 2026

Summary by CodeRabbit

  • New Features

    • Dockerized deployment to AWS EC2 with automated GitHub Actions workflow
    • Local Docker Compose setup with PostgreSQL for development
    • REST API endpoints for users and posts (create, read, publish, delete)
  • Documentation

    • Comprehensive README covering local setup, API usage, and cloud deployment
  • Chores

    • Project configs, env example, ignore rules, TypeScript/Prisma setup, Dockerfile, and DB migrations added

Copilot AI review requested due to automatic review settings March 17, 2026 09:45
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 17, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a full TypeScript Express + Prisma REST API and deployment setup: Dockerfile, docker-compose, Prisma schema/migrations, app code (routes, Prisma client, server), GitHub Actions workflow to build/push to ECR and SSH-deploy to EC2, docs, .gitignore/.dockerignore, and .env example.

Changes

Cohort / File(s) Summary
Containerization & Local Dev
deployment-platforms/rest-express-docker-aws-ec2/Dockerfile, deployment-platforms/rest-express-docker-aws-ec2/docker-compose.yml, deployment-platforms/rest-express-docker-aws-ec2/.dockerignore, deployment-platforms/rest-express-docker-aws-ec2/.gitignore
Added multi-stage Dockerfile (build + runtime), docker-compose with Postgres service and migration step, and ignore files excluding node_modules, dist, .env, prisma/generated.
CI/CD & Deployment
deployment-platforms/rest-express-docker-aws-ec2/.github/workflows/deploy.yml
New GitHub Actions workflow: builds image, pushes to ECR (SHA + latest), SSHes to EC2, authenticates to ECR, pulls image, runs migrations in a temporary container, stops/removes existing container, starts new container with env and port mapping, verifies health, and prunes old images.
Project Metadata & Tooling
deployment-platforms/rest-express-docker-aws-ec2/package.json, deployment-platforms/rest-express-docker-aws-ec2/tsconfig.json, deployment-platforms/rest-express-docker-aws-ec2/.env.example
Added package.json with scripts and dependencies (Express, Prisma, TypeScript tooling), tsconfig.json, and .env.example containing a DATABASE_URL template.
Prisma: Schema, Config & Migrations
deployment-platforms/rest-express-docker-aws-ec2/prisma/schema.prisma, deployment-platforms/rest-express-docker-aws-ec2/prisma.config.ts, deployment-platforms/rest-express-docker-aws-ec2/prisma/migrations/.../migration.sql, deployment-platforms/rest-express-docker-aws-ec2/prisma/migrations/migration_lock.toml
Introduced Prisma config, PostgreSQL datasource and generator output, User and Post models (one-to-many), initial migration SQL and migration lock file.
Application Code: Server & DB Client
deployment-platforms/rest-express-docker-aws-ec2/src/index.ts, deployment-platforms/rest-express-docker-aws-ec2/src/lib/prisma.ts
Added Express entrypoint that mounts routers and starts the server; added Prisma client initializer using a Postgres pool and env validation.
API Routes
deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts, deployment-platforms/rest-express-docker-aws-ec2/src/routes/user.routes.ts
New routers: POST /user (create user) and post endpoints (feed, get by id, create, publish, delete) with input validation, Prisma-backed CRUD, and error handling.
Documentation
deployment-platforms/rest-express-docker-aws-ec2/README.md
Added README documenting prerequisites, local development (Docker Compose/local), Prisma migrations, API examples, and AWS ECR/EC2 GitHub Actions deployment instructions.

Sequence Diagram(s)

sequenceDiagram
    participant GHA as GitHub Actions
    participant ECR as AWS ECR
    participant EC2 as EC2 Instance
    participant App as Docker Container (App)
    participant DB as PostgreSQL

    GHA->>GHA: Checkout & build image (commit SHA)
    GHA->>ECR: Login & push image (SHA + latest)
    GHA->>EC2: SSH to instance
    EC2->>ECR: Authenticate & pull image
    EC2->>EC2: Stop / remove existing container
    EC2->>EC2: Run migration container (uses DATABASE_URL)
    EC2->>App: Start new container (map port, env)
    EC2->>App: Health check / verify running
    EC2->>EC2: Prune old images
    GHA->>GHA: Report workflow result
Loading
sequenceDiagram
    participant Client as HTTP Client
    participant Express as Express Server
    participant Prisma as Prisma Client
    participant DB as PostgreSQL

    Client->>Express: GET /feed
    Express->>Prisma: findMany(Post with author)
    Prisma->>DB: SELECT posts JOIN users
    DB-->>Prisma: rows
    Prisma-->>Express: posts[]
    Express-->>Client: JSON response

    Client->>Express: POST /user
    Express->>Prisma: create(User)
    Prisma->>DB: INSERT user
    DB-->>Prisma: created row
    Prisma-->>Express: user
    Express-->>Client: JSON response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a new deployment example for a REST Express application with Docker on AWS EC2.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new deployment example under deployment-platforms/ demonstrating a Prisma-backed Express REST API deployed via Docker to AWS EC2 (with a sample GitHub Actions workflow).

Changes:

  • Introduces a TypeScript Express REST API with Prisma models/routes for User and Post.
  • Adds Dockerfile + docker-compose setup intended to run the app with Postgres locally.
  • Adds documentation and a sample GitHub Actions workflow for building/pushing to ECR and deploying to EC2.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
deployment-platforms/rest-express-docker-aws-ec2/tsconfig.json TypeScript build configuration for the example app.
deployment-platforms/rest-express-docker-aws-ec2/src/index.ts Express app bootstrap and router mounting.
deployment-platforms/rest-express-docker-aws-ec2/src/lib/prisma.ts Prisma Client initialization using the Postgres adapter.
deployment-platforms/rest-express-docker-aws-ec2/src/routes/user.routes.ts REST endpoint for creating users.
deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts REST endpoints for reading/creating/publishing/deleting posts.
deployment-platforms/rest-express-docker-aws-ec2/prisma/schema.prisma Prisma schema defining User and Post models.
deployment-platforms/rest-express-docker-aws-ec2/prisma.config.ts Prisma CLI configuration (schema, migrations path, datasource env).
deployment-platforms/rest-express-docker-aws-ec2/package.json Example app dependencies and scripts.
deployment-platforms/rest-express-docker-aws-ec2/Dockerfile Multi-stage container build for the example API.
deployment-platforms/rest-express-docker-aws-ec2/docker-compose.yml Local orchestration for app + Postgres.
deployment-platforms/rest-express-docker-aws-ec2/.github/workflows/deploy.yml Sample CI/CD workflow for ECR build/push and EC2 deploy via SSH.
deployment-platforms/rest-express-docker-aws-ec2/README.md End-to-end instructions for local run and EC2 deployment.
deployment-platforms/rest-express-docker-aws-ec2/.env.example Sample environment variable template.
deployment-platforms/rest-express-docker-aws-ec2/.gitignore Ignores local artifacts for the example directory.
deployment-platforms/rest-express-docker-aws-ec2/.dockerignore Reduces Docker build context for the example directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@DiluDevX
Copy link
Author

Related to #8459@aidankmcalister approved the idea there.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (5)
deployment-platforms/rest-express-docker-aws-ec2/prisma/schema.prisma (1)

1-4: Prefer generating the client under src for this compiled app.

prisma-client emits plain TypeScript into the configured output directory. If the app imports a client generated under prisma/generated, TypeScript can infer the project root as the common source root, which moves the built entrypoint to dist/src/index.js instead of the dist/index.js path used by deployment-platforms/rest-express-docker-aws-ec2/package.json. Generating into ../src/generated/prisma avoids that mismatch and matches Prisma's documented bundled-app layout. (prisma.io)

♻️ Suggested generator output change
 generator client {
   provider = "prisma-client"
-  output   = "./generated"
+  output   = "../src/generated/prisma"
 }

You would also need to update the import path in deployment-platforms/rest-express-docker-aws-ec2/src/lib/prisma.ts.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/prisma/schema.prisma` around
lines 1 - 4, Update the Prisma generator output to emit the client into the app
source tree (change the generator block `generator client { ... }` output to
"../src/generated/prisma") so the generated TypeScript lives under src and the
compiled build resolves to dist/index.js; then update the import in
src/lib/prisma.ts to use the new client path (the new generated prisma client
name/location) so imports point to ../src/generated/prisma instead of the old
generated path. Ensure the generator `provider = "prisma-client"` line remains
unchanged.
deployment-platforms/rest-express-docker-aws-ec2/package.json (1)

5-9: Make Prisma codegen part of the scripted workflow.

Prisma's setup docs require prisma generate to create and refresh the client API. Because this example also keeps prisma/generated out of version control, the current build and dev scripts depend on some out-of-band step to make a clean checkout work. Wiring codegen into the scripts would make the example reproducible from scratch. (prisma.io)

♻️ Suggested script update
   "scripts": {
-    "build": "tsc",
-    "dev": "tsx src/index.ts",
+    "generate": "prisma generate",
+    "build": "prisma generate && tsc",
+    "dev": "prisma generate && tsx src/index.ts",
     "start": "node dist/index.js"
   },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/package.json` around lines 5
- 9, The package.json scripts currently run "build", "dev", and "start" without
running Prisma code generation; update the scripts so Prisma client generation
runs as part of the workflow (e.g., run "prisma generate" before "tsc" in the
"build" script and before starting the dev server in the "dev" script) so that
the Prisma client in prisma/generated is created on a fresh checkout; modify the
"build" and "dev" script entries (the "build" and "dev" script names in
package.json) to invoke prisma generate first, ensuring reproducible builds and
local development.
deployment-platforms/rest-express-docker-aws-ec2/src/index.ts (1)

12-14: Prefer env-driven port binding.

Using a fixed 3000 limits portability. Read PORT with a fallback.

Proposed fix
-app.listen(3000, () =>
-  console.log('Server ready at: http://localhost:3000'),
-)
+const port = Number(process.env.PORT ?? 3000)
+app.listen(port, () =>
+  console.log(`Server ready at: http://localhost:${port}`),
+)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/src/index.ts` around lines
12 - 14, Replace the hard-coded port in app.listen with an environment-driven
value: read process.env.PORT (with a safe fallback like 3000), store it in a
port variable (e.g., const port = parseInt(process.env.PORT, 10) || 3000), use
that variable in app.listen(port, ...) and update the console.log message to
reference the port variable so the server binds to the configured port at
runtime.
deployment-platforms/rest-express-docker-aws-ec2/.github/workflows/deploy.yml (1)

80-89: Container presence check is not a readiness check.

docker ps only confirms process existence, not API health. Add an HTTP health probe (or Docker healthcheck status) before declaring success.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@deployment-platforms/rest-express-docker-aws-ec2/.github/workflows/deploy.yml`
around lines 80 - 89, The workflow currently uses docker ps to check
CONTAINER_NAME existence but not service readiness; replace or augment that
check with an actual health probe by polling either Docker health status (docker
inspect --format '{{.State.Health.Status}}' "$CONTAINER_NAME") until it reports
"healthy" with a timeout, or perform HTTP requests (curl --fail --max-time 2
http://localhost:<PORT> | grep -q ...) against the container's exposed port with
retries and a total timeout; on success echo the container is healthy and show
docker ps output, on failure print docker logs "$CONTAINER_NAME" --tail 50 and
exit 1. Ensure the probe uses configurable variables (CONTAINER_NAME, PORT,
RETRIES, SLEEP) so it can be tuned.
deployment-platforms/rest-express-docker-aws-ec2/docker-compose.yml (1)

7-7: Avoid hardcoded DB credentials in committed compose config.

Parameterize these values via .env to reduce accidental credential reuse and secret-scanner noise.

Proposed fix
-      DATABASE_URL: postgresql://prisma:prisma@postgres:5432/prisma
+      DATABASE_URL: ${DATABASE_URL}

-      POSTGRES_USER: prisma
-      POSTGRES_PASSWORD: prisma
-      POSTGRES_DB: prisma
+      POSTGRES_USER: ${POSTGRES_USER:-prisma}
+      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-prisma}
+      POSTGRES_DB: ${POSTGRES_DB:-prisma}

Also applies to: 17-19

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/docker-compose.yml` at line
7, Replace the hardcoded DATABASE_URL in docker-compose.yml with
environment-variable references and load them from a .env file: remove the
literal "postgresql://prisma:prisma@postgres:5432/prisma" and instead reference
e.g. ${DATABASE_URL} (or split into ${DB_USER}, ${DB_PASS}, ${DB_HOST},
${DB_NAME}) so credentials are not committed; add a .env.example with
placeholder values and update any related service entries (postgres/service
environment lines at the same block, e.g. the entries referenced on lines 17-19
in the diff) to use the same variables.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@deployment-platforms/rest-express-docker-aws-ec2/.github/workflows/deploy.yml`:
- Around line 73-78: The workflow currently starts the app with docker run
directly (using CONTAINER_NAME, CONTAINER_PORT, DATABASE_URL and image
"$ECR_REGISTRY/$ECR_REPOSITORY:${{ github.sha }}"); add a step that runs the
image to execute the schema migration command first (run a transient container
with --rm, passing DATABASE_URL and any other needed envs) and ensure it exits
non‑zero on failure before proceeding; only after that migration container
completes successfully, run the existing docker run for the app container.
Reference the image name "$ECR_REGISTRY/$ECR_REPOSITORY:${{ github.sha }}" and
the existing docker run invocation when adding the migration run and failure
handling.
- Around line 5-6: The workflow's push trigger only lists the branches array
with "main", so pushes/merges into "latest" won't run; update the branches array
in the workflow (the "branches:" key) to include "latest" (or both "main" and
"latest") so that pushes/merges to the latest branch trigger the deploy; ensure
the "branches:" entry that currently contains "main" is modified to add "latest"
(or replace with both branch names).

In `@deployment-platforms/rest-express-docker-aws-ec2/Dockerfile`:
- Line 26: The runtime image omits devDependencies via the RUN npm ci --omit=dev
step while startup runs npx prisma migrate deploy, so the Prisma CLI (prisma) is
missing; fix by either moving the Prisma package from devDependencies into
dependencies in package.json so it is installed in the runner image, or run
migrations earlier (e.g., invoke npx prisma migrate deploy in the builder stage
or perform migrations in a separate init container) and keep RUN npm ci
--omit=dev as-is; update package.json (prisma entry) or adjust the
Dockerfile/builder or docker-compose startup flow accordingly.

In `@deployment-platforms/rest-express-docker-aws-ec2/README.md`:
- Line 163: Update the README sentence that mentions the workflow to use the
official capitalization "GitHub" (capitalize the H) — edit the text describing
.github/workflows/deploy.yml so "GitHub Actions" and any other occurrences of
"GitHub" are correctly capitalized; locate the sentence in README.md that
currently reads "GitHub actions" or similar and change it to "GitHub Actions".

In `@deployment-platforms/rest-express-docker-aws-ec2/src/lib/prisma.ts`:
- Around line 4-5: The code currently uses process.env.DATABASE_URL! when
constructing PrismaPg and can crash opaquely; add an explicit guard that reads
DATABASE_URL into a local const (e.g., const databaseUrl =
process.env.DATABASE_URL), throw a clear error if falsy (e.g., throw new
Error('Missing DATABASE_URL env var')), then use that validated databaseUrl when
creating the PrismaPg adapter and passing it to new PrismaClient (symbols:
PrismaPg, PrismaClient, prisma, process.env.DATABASE_URL).

In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts`:
- Around line 17-20: Validate the route path id from req.params before
converting and querying: check that id is a numeric positive integer (e.g.,
parseInt(id, 10), ensure Number.isInteger(value) and value > 0) and immediately
return res.status(400).json(...) on failure; apply this guard before calling
prisma.post.findUnique, prisma.post.update, and prisma.post.delete (or any
handler that does Number(id)) so invalid IDs never reach the database query.
- Around line 50-52: The catch blocks in post.routes.ts currently swallow all
exceptions and always return 404; change each catch { ... } to catch (err) { ...
} and differentiate missing-record errors from other failures: if err clearly
indicates a not-found condition (e.g., err.name === 'NotFoundError' or
err.message contains 'not found') respond with res.status(404).json(...),
otherwise log the error and respond with res.status(500).json({ error: 'Internal
server error' }). Apply this change to both catch sites in the file so only true
missing-record errors return 404 and all other exceptions return 500.
- Around line 29-38: Validate request payload in the postRouter.post handler:
check req.body for non-empty title and authorEmail and return
res.status(400).json(...) when missing/invalid; before calling
prisma.post.create, verify the author exists (e.g., using prisma.user.findUnique
or findFirst with email === authorEmail) and return res.status(404).json(...) if
not found; only then call prisma.post.create (as currently used) and keep a
try/catch to return a 500 on unexpected errors. Ensure you reference the
existing postRouter.post handler, prisma.post.create, and the request body
fields title/authorEmail when implementing these checks.

In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/user.routes.ts`:
- Around line 7-12: The POST /user route handler currently forwards req.body to
prisma.user.create without validation and doesn't map unique-constraint errors;
wrap the logic in a try/catch in the userRouter.post handler, validate that
email and name are present and that email is a valid format (return 400 for
missing/invalid input), then call prisma.user.create; in the catch block detect
Prisma.PrismaClientKnownRequestError (check error.code === 'P2002') and return
res.status(409).json({ message: 'Email already exists' }), otherwise rethrow or
return a 500 for unexpected errors. Use the existing prisma.user.create and the
userRouter.post handler names to locate where to apply these changes.

---

Nitpick comments:
In
`@deployment-platforms/rest-express-docker-aws-ec2/.github/workflows/deploy.yml`:
- Around line 80-89: The workflow currently uses docker ps to check
CONTAINER_NAME existence but not service readiness; replace or augment that
check with an actual health probe by polling either Docker health status (docker
inspect --format '{{.State.Health.Status}}' "$CONTAINER_NAME") until it reports
"healthy" with a timeout, or perform HTTP requests (curl --fail --max-time 2
http://localhost:<PORT> | grep -q ...) against the container's exposed port with
retries and a total timeout; on success echo the container is healthy and show
docker ps output, on failure print docker logs "$CONTAINER_NAME" --tail 50 and
exit 1. Ensure the probe uses configurable variables (CONTAINER_NAME, PORT,
RETRIES, SLEEP) so it can be tuned.

In `@deployment-platforms/rest-express-docker-aws-ec2/docker-compose.yml`:
- Line 7: Replace the hardcoded DATABASE_URL in docker-compose.yml with
environment-variable references and load them from a .env file: remove the
literal "postgresql://prisma:prisma@postgres:5432/prisma" and instead reference
e.g. ${DATABASE_URL} (or split into ${DB_USER}, ${DB_PASS}, ${DB_HOST},
${DB_NAME}) so credentials are not committed; add a .env.example with
placeholder values and update any related service entries (postgres/service
environment lines at the same block, e.g. the entries referenced on lines 17-19
in the diff) to use the same variables.

In `@deployment-platforms/rest-express-docker-aws-ec2/package.json`:
- Around line 5-9: The package.json scripts currently run "build", "dev", and
"start" without running Prisma code generation; update the scripts so Prisma
client generation runs as part of the workflow (e.g., run "prisma generate"
before "tsc" in the "build" script and before starting the dev server in the
"dev" script) so that the Prisma client in prisma/generated is created on a
fresh checkout; modify the "build" and "dev" script entries (the "build" and
"dev" script names in package.json) to invoke prisma generate first, ensuring
reproducible builds and local development.

In `@deployment-platforms/rest-express-docker-aws-ec2/prisma/schema.prisma`:
- Around line 1-4: Update the Prisma generator output to emit the client into
the app source tree (change the generator block `generator client { ... }`
output to "../src/generated/prisma") so the generated TypeScript lives under src
and the compiled build resolves to dist/index.js; then update the import in
src/lib/prisma.ts to use the new client path (the new generated prisma client
name/location) so imports point to ../src/generated/prisma instead of the old
generated path. Ensure the generator `provider = "prisma-client"` line remains
unchanged.

In `@deployment-platforms/rest-express-docker-aws-ec2/src/index.ts`:
- Around line 12-14: Replace the hard-coded port in app.listen with an
environment-driven value: read process.env.PORT (with a safe fallback like
3000), store it in a port variable (e.g., const port =
parseInt(process.env.PORT, 10) || 3000), use that variable in app.listen(port,
...) and update the console.log message to reference the port variable so the
server binds to the configured port at runtime.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 721f24a6-1b86-47af-938f-1bb3128fe43e

📥 Commits

Reviewing files that changed from the base of the PR and between 248f85b and 79c27e5.

📒 Files selected for processing (15)
  • deployment-platforms/rest-express-docker-aws-ec2/.dockerignore
  • deployment-platforms/rest-express-docker-aws-ec2/.env.example
  • deployment-platforms/rest-express-docker-aws-ec2/.github/workflows/deploy.yml
  • deployment-platforms/rest-express-docker-aws-ec2/.gitignore
  • deployment-platforms/rest-express-docker-aws-ec2/Dockerfile
  • deployment-platforms/rest-express-docker-aws-ec2/README.md
  • deployment-platforms/rest-express-docker-aws-ec2/docker-compose.yml
  • deployment-platforms/rest-express-docker-aws-ec2/package.json
  • deployment-platforms/rest-express-docker-aws-ec2/prisma.config.ts
  • deployment-platforms/rest-express-docker-aws-ec2/prisma/schema.prisma
  • deployment-platforms/rest-express-docker-aws-ec2/src/index.ts
  • deployment-platforms/rest-express-docker-aws-ec2/src/lib/prisma.ts
  • deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts
  • deployment-platforms/rest-express-docker-aws-ec2/src/routes/user.routes.ts
  • deployment-platforms/rest-express-docker-aws-ec2/tsconfig.json

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts (2)

35-43: ⚠️ Potential issue | 🟠 Major

Validate create payload and handle unknown author explicitly (still unresolved).

title / authorEmail are unchecked, and missing author can bubble into an internal error path. Return controlled 400/404 responses first.

Proposed fix
 postRouter.post('/post', async (req: Request, res: Response) => {
   const { title, content, authorEmail } = req.body
-  const post = await prisma.post.create({
-    data: {
-      title,
-      content,
-      author: { connect: { email: authorEmail } },
-    },
-  })
-  res.json(post)
+  if (
+    typeof title !== 'string' || !title.trim() ||
+    typeof authorEmail !== 'string' || !authorEmail.trim()
+  ) {
+    res.status(400).json({ error: 'title and authorEmail are required' })
+    return
+  }
+
+  const author = await prisma.user.findUnique({ where: { email: authorEmail } })
+  if (!author) {
+    res.status(404).json({ error: `Author with email ${authorEmail} not found` })
+    return
+  }
+
+  const post = await prisma.post.create({
+    data: {
+      title: title.trim(),
+      content,
+      author: { connect: { email: authorEmail } },
+    },
+  })
+  res.status(201).json(post)
 })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts`
around lines 35 - 43, The POST handler in postRouter (the async callback
creating posts via prisma.post.create) does not validate title/authorEmail and
lets a missing author surface as an internal error; update the handler to first
validate presence/format of title and authorEmail and return a 400 when invalid,
then query for the author using prisma.user.findUnique (or findFirst) with the
provided authorEmail and return a 404 if not found, and only then call
prisma.post.create with the validated data (title, content, author connect) so
errors are controlled and clear.

19-21: ⚠️ Potential issue | 🟠 Major

Tighten ID validation to positive integers only (still unresolved).

Current checks allow 0 and negative integers. Reject non-positive IDs with 400 before Prisma calls.

Proposed fix (shared helper)
+function parsePositiveId(value: string): number | null {
+  const parsed = Number.parseInt(value, 10)
+  return Number.isInteger(parsed) && parsed > 0 ? parsed : null
+}
+
 postRouter.get('/post/:id', async (req: Request, res: Response) => {
   const { id } = req.params
-  const postId = Number(id)
-  if (!Number.isInteger(postId)) {
+  const postId = parsePositiveId(id)
+  if (!postId) {
     res.status(400).json({ error: `Invalid post ID: ${id}` })
     return
   }

Also applies to: 50-52, 77-79

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts`
around lines 19 - 21, The current validation casts id to postId with Number(id)
and only checks Number.isInteger(postId), which allows 0 and negatives; update
the validation in the handler(s) that use postId (the variable postId derived
from id) to require postId be an integer greater than 0 (e.g.,
Number.isInteger(postId) && postId > 0) and return res.status(400).json({ error:
`Invalid post ID: ${id}` }) for any non-positive or non-integer values; extract
this logic into a small shared helper (e.g., isValidPositiveInt) and use it in
all affected handlers (the checks around lines where postId is created: the
blocks referencing postId at 19-21, 50-52, and 77-79) to avoid duplication.
🧹 Nitpick comments (4)
deployment-platforms/rest-express-docker-aws-ec2/tsconfig.json (1)

5-5: Add an explicit typecheck script and integrate it into development workflows.

The dev script (tsx src/index.ts) skips type checking; type errors are only caught during npm run build. Add a typecheck script with tsc --noEmit and run it during development and CI to catch issues earlier.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/tsconfig.json` at line 5,
Add an explicit typecheck step by adding a "typecheck" npm script that runs "tsc
--noEmit" and invoke it from development and CI: update the existing "dev"
workflow (the script that currently runs "tsx src/index.ts") to run type
checking before launching tsx (either by adding a "predev" script or
chaining/instrumenting the "dev" script to run "npm run typecheck && tsx
src/index.ts"), and ensure CI pipelines call "npm run typecheck" (in addition to
"npm run build") so type errors are caught early; reference the "dev" script,
the new "typecheck" script, and the existing "build" script when making changes.
deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts (1)

44-45: Use 201 Created for successful resource creation.

For POST /post, returning 201 is a better HTTP contract than 200.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts`
around lines 44 - 45, The POST /post handler currently responds with
res.json(post) returning 200; update the response to use HTTP 201 for resource
creation by replacing that call with res.status(201).json(post) in the POST
route handler (the callback where res.json(post) is invoked) so the route
returns "201 Created" with the created post.
deployment-platforms/rest-express-docker-aws-ec2/prisma/migrations/20240101000000_init/migration.sql (1)

11-25: Add an index for Post.authorId to avoid FK hot-path scans.

This migration adds the FK, but not its supporting index. For common joins/filtering on author, this can degrade quickly as data grows.

Proposed migration addition
 -- AddForeignKey
 ALTER TABLE "Post" ADD CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- CreateIndex
+CREATE INDEX "Post_authorId_idx" ON "Post"("authorId");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@deployment-platforms/rest-express-docker-aws-ec2/prisma/migrations/20240101000000_init/migration.sql`
around lines 11 - 25, Add a supporting index for the foreign key column by
creating (for example) CREATE INDEX "Post_authorId_idx" ON "Post"("authorId") in
the same migration (either immediately before or after the ALTER TABLE that adds
the constraint "Post_authorId_fkey"); ensure the index name is unique and the
index targets the "Post"."authorId" column so common joins/filters on
Post.authorId use the index.
deployment-platforms/rest-express-docker-aws-ec2/README.md (1)

125-135: Add EC2 AWS credentials configuration.

The workflow SSHes into EC2 and runs aws ecr get-login-password to authenticate with ECR (see context snippet from deploy.yml lines 50-100). For this to work, the EC2 instance must be configured with AWS credentials. Consider adding a step after Docker installation:

Option 1 (recommended): Attach an IAM role to the EC2 instance with ECR pull permissions (AmazonEC2ContainerRegistryReadOnly policy).

Option 2: Configure AWS CLI credentials on the instance using aws configure.

Without this, the deployment will fail when attempting to pull the Docker image from ECR.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/README.md` around lines 125
- 135, The README currently instructs launching an EC2 instance and opening
CONTAINER_PORT but omits configuring AWS credentials needed by the deployment
workflow that runs aws ecr get-login-password; update the instructions to
require adding AWS credentials to the EC2 instance by recommending Option 1:
attach an IAM instance role with AmazonEC2ContainerRegistryReadOnly (preferred)
or Option 2: configure AWS CLI credentials via aws configure on the instance,
and mention this is necessary for the deploy.yml step that authenticates to ECR
before pulling the Docker image.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@deployment-platforms/rest-express-docker-aws-ec2/README.md`:
- Line 163: The long single-sentence paragraph in the README under the "3. How
deployment works" section is hard to read; split it into a short intro sentence
and a numbered or bulleted list that steps through each action (authenticate
with AWS; build image with Buildx and caching; push to ECR with commit-SHA and
latest tags; SSH to EC2; run prisma migrate deploy in a one-off container; pull
new image; stop/remove old container if present; start new container with
DATABASE_URL; wait 5s and verify running, printing logs and exiting non-zero on
failure; prune old images). Update the README.md section text accordingly and
keep the mention of the workflow file name and behavior in the intro sentence.

---

Duplicate comments:
In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts`:
- Around line 35-43: The POST handler in postRouter (the async callback creating
posts via prisma.post.create) does not validate title/authorEmail and lets a
missing author surface as an internal error; update the handler to first
validate presence/format of title and authorEmail and return a 400 when invalid,
then query for the author using prisma.user.findUnique (or findFirst) with the
provided authorEmail and return a 404 if not found, and only then call
prisma.post.create with the validated data (title, content, author connect) so
errors are controlled and clear.
- Around line 19-21: The current validation casts id to postId with Number(id)
and only checks Number.isInteger(postId), which allows 0 and negatives; update
the validation in the handler(s) that use postId (the variable postId derived
from id) to require postId be an integer greater than 0 (e.g.,
Number.isInteger(postId) && postId > 0) and return res.status(400).json({ error:
`Invalid post ID: ${id}` }) for any non-positive or non-integer values; extract
this logic into a small shared helper (e.g., isValidPositiveInt) and use it in
all affected handlers (the checks around lines where postId is created: the
blocks referencing postId at 19-21, 50-52, and 77-79) to avoid duplication.

---

Nitpick comments:
In
`@deployment-platforms/rest-express-docker-aws-ec2/prisma/migrations/20240101000000_init/migration.sql`:
- Around line 11-25: Add a supporting index for the foreign key column by
creating (for example) CREATE INDEX "Post_authorId_idx" ON "Post"("authorId") in
the same migration (either immediately before or after the ALTER TABLE that adds
the constraint "Post_authorId_fkey"); ensure the index name is unique and the
index targets the "Post"."authorId" column so common joins/filters on
Post.authorId use the index.

In `@deployment-platforms/rest-express-docker-aws-ec2/README.md`:
- Around line 125-135: The README currently instructs launching an EC2 instance
and opening CONTAINER_PORT but omits configuring AWS credentials needed by the
deployment workflow that runs aws ecr get-login-password; update the
instructions to require adding AWS credentials to the EC2 instance by
recommending Option 1: attach an IAM instance role with
AmazonEC2ContainerRegistryReadOnly (preferred) or Option 2: configure AWS CLI
credentials via aws configure on the instance, and mention this is necessary for
the deploy.yml step that authenticates to ECR before pulling the Docker image.

In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts`:
- Around line 44-45: The POST /post handler currently responds with
res.json(post) returning 200; update the response to use HTTP 201 for resource
creation by replacing that call with res.status(201).json(post) in the POST
route handler (the callback where res.json(post) is invoked) so the route
returns "201 Created" with the created post.

In `@deployment-platforms/rest-express-docker-aws-ec2/tsconfig.json`:
- Line 5: Add an explicit typecheck step by adding a "typecheck" npm script that
runs "tsc --noEmit" and invoke it from development and CI: update the existing
"dev" workflow (the script that currently runs "tsx src/index.ts") to run type
checking before launching tsx (either by adding a "predev" script or
chaining/instrumenting the "dev" script to run "npm run typecheck && tsx
src/index.ts"), and ensure CI pipelines call "npm run typecheck" (in addition to
"npm run build") so type errors are caught early; reference the "dev" script,
the new "typecheck" script, and the existing "build" script when making changes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e02283f4-b42b-4001-b3f4-beb0eb3ffe86

📥 Commits

Reviewing files that changed from the base of the PR and between 79c27e5 and acbb0be.

📒 Files selected for processing (8)
  • deployment-platforms/rest-express-docker-aws-ec2/.github/workflows/deploy.yml
  • deployment-platforms/rest-express-docker-aws-ec2/Dockerfile
  • deployment-platforms/rest-express-docker-aws-ec2/README.md
  • deployment-platforms/rest-express-docker-aws-ec2/package.json
  • deployment-platforms/rest-express-docker-aws-ec2/prisma/migrations/20240101000000_init/migration.sql
  • deployment-platforms/rest-express-docker-aws-ec2/prisma/migrations/migration_lock.toml
  • deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts
  • deployment-platforms/rest-express-docker-aws-ec2/tsconfig.json
✅ Files skipped from review due to trivial changes (1)
  • deployment-platforms/rest-express-docker-aws-ec2/prisma/migrations/migration_lock.toml
🚧 Files skipped from review as they are similar to previous changes (3)
  • deployment-platforms/rest-express-docker-aws-ec2/.github/workflows/deploy.yml
  • deployment-platforms/rest-express-docker-aws-ec2/Dockerfile
  • deployment-platforms/rest-express-docker-aws-ec2/package.json

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts (1)

39-54: ⚠️ Potential issue | 🟠 Major

Handle non-existent author and database errors.

The handler validates that title and authorEmail are provided, but if authorEmail doesn't exist in the database, Prisma's connect will throw a P2025 error that is currently unhandled. This will surface as a 500 error instead of a meaningful 404 response.

🛠️ Proposed fix to handle author not found and other errors
 postRouter.post('/post', async (req: Request, res: Response) => {
   const { title, authorEmail, content } = req.body
   if (!title || !authorEmail) {
     res.status(400).json({ error: 'title and authorEmail are required' })
     return
   }
-  const post = await prisma.post.create({
-    data: {
-      title,
-      content,
-      author: { connect: { email: authorEmail } },
-    },
-  })
-  res.json(post)
+  try {
+    const post = await prisma.post.create({
+      data: {
+        title,
+        content,
+        author: { connect: { email: authorEmail } },
+      },
+    })
+    res.status(201).json(post)
+  } catch (error: unknown) {
+    if (
+      error instanceof Prisma.PrismaClientKnownRequestError &&
+      error.code === 'P2025'
+    ) {
+      res.status(404).json({ error: `Author with email ${authorEmail} not found` })
+      return
+    }
+    res.status(500).json({ error: 'Internal server error' })
+  }
 })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts`
around lines 39 - 54, The POST /post handler currently calls prisma.post.create
(inside the postRouter.post async callback) without handling the case where
authorEmail doesn't exist and Prisma throws a P2025; modify the handler to
either first check author existence with prisma.user.findUnique({ where: {
email: authorEmail } }) and return res.status(404) if missing, or wrap
prisma.post.create in a try/catch that inspects
Prisma.PrismaClientKnownRequestError with code 'P2025' and returns a 404 "author
not found" response, and for all other errors return a 500 with a generic error
message; ensure the changes reference the postRouter.post handler and
prisma.post.create (or prisma.user.findUnique) so the missing-author and DB
errors are handled gracefully.
🧹 Nitpick comments (1)
deployment-platforms/rest-express-docker-aws-ec2/src/routes/user.routes.ts (1)

7-33: Good implementation of validation and error handling.

The handler now includes proper input validation for email presence and format, and correctly handles the Prisma P2002 unique constraint error with a 409 response. This addresses the concerns from the prior review.

One minor improvement: consider returning 201 Created status for successful resource creation instead of the default 200.

,

💡 Optional: Return 201 for created resources
     const user = await prisma.user.create({
       data: { email, name },
     })
-    res.json(user)
+    res.status(201).json(user)
   } catch (error: unknown) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/user.routes.ts`
around lines 7 - 33, The POST /user handler currently returns the created user
with a 200 status; update the response in the userRouter.post async handler (the
block that awaits prisma.user.create) to return HTTP 201 Created (and optionally
set a Location header pointing to the new resource) instead of res.json(...)
with the default 200 so successful creations use the proper status code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts`:
- Around line 16-23: The /feed route handler (postRouter.get('/feed')) lacks
error handling around the prisma.post.findMany call; wrap the async handler body
in a try/catch, catch any errors from prisma.post.findMany, log the error (or
use an existing logger) and respond with an appropriate 500 response (e.g.,
res.status(500).json({ error: 'Internal server error' })) so the request does
not cause an unhandled rejection.
- Around line 25-37: The GET /post/:id route handler (postRouter.get async
callback using parsePostId and prisma.post.findUnique) lacks try/catch for
Prisma/database errors; wrap the async logic (after parsePostId) in a try/catch,
call prisma.post.findUnique inside the try, and in the catch log the error and
return res.status(500).json({ error: 'Internal server error' }) (or include
brief error info if appropriate) so DB connection failures or other exceptions
are handled instead of crashing the process.

---

Duplicate comments:
In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts`:
- Around line 39-54: The POST /post handler currently calls prisma.post.create
(inside the postRouter.post async callback) without handling the case where
authorEmail doesn't exist and Prisma throws a P2025; modify the handler to
either first check author existence with prisma.user.findUnique({ where: {
email: authorEmail } }) and return res.status(404) if missing, or wrap
prisma.post.create in a try/catch that inspects
Prisma.PrismaClientKnownRequestError with code 'P2025' and returns a 404 "author
not found" response, and for all other errors return a 500 with a generic error
message; ensure the changes reference the postRouter.post handler and
prisma.post.create (or prisma.user.findUnique) so the missing-author and DB
errors are handled gracefully.

---

Nitpick comments:
In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/user.routes.ts`:
- Around line 7-33: The POST /user handler currently returns the created user
with a 200 status; update the response in the userRouter.post async handler (the
block that awaits prisma.user.create) to return HTTP 201 Created (and optionally
set a Location header pointing to the new resource) instead of res.json(...)
with the default 200 so successful creations use the proper status code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f34e85ca-19f0-496f-8536-f09940bcf727

📥 Commits

Reviewing files that changed from the base of the PR and between acbb0be and c1acc0d.

📒 Files selected for processing (6)
  • deployment-platforms/rest-express-docker-aws-ec2/.github/workflows/deploy.yml
  • deployment-platforms/rest-express-docker-aws-ec2/package.json
  • deployment-platforms/rest-express-docker-aws-ec2/src/index.ts
  • deployment-platforms/rest-express-docker-aws-ec2/src/lib/prisma.ts
  • deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts
  • deployment-platforms/rest-express-docker-aws-ec2/src/routes/user.routes.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • deployment-platforms/rest-express-docker-aws-ec2/src/lib/prisma.ts
  • deployment-platforms/rest-express-docker-aws-ec2/package.json
  • deployment-platforms/rest-express-docker-aws-ec2/src/index.ts
  • deployment-platforms/rest-express-docker-aws-ec2/.github/workflows/deploy.yml

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
deployment-platforms/rest-express-docker-aws-ec2/package.json (1)

11-18: Move prisma to devDependencies.

The prisma CLI package is used for migrations and code generation during development and CI, but is not required at runtime. Moving it to devDependencies reduces the production image size.

♻️ Proposed fix
   "dependencies": {
     "@prisma/adapter-pg": "7.0.0",
     "@prisma/client": "7.0.0",
     "dotenv": "^17.2.1",
     "express": "5.1.0",
-    "pg": "^8.16.3",
-    "prisma": "7.0.0"
+    "pg": "^8.16.3"
   },
   "devDependencies": {
     "@types/express": "5.0.5",
     "@types/node": "22.18.12",
     "@types/pg": "^8.15.6",
+    "prisma": "7.0.0",
     "tsx": "^4.20.6",
     "typescript": "5.8.2"
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/package.json` around lines
11 - 18, The package.json currently lists "prisma" under "dependencies"; move it
to "devDependencies" so the Prisma CLI is not installed in production images.
Edit the dependencies object to remove the "prisma": "7.0.0" entry and add the
same "prisma": "7.0.0" entry under a devDependencies object (or create
devDependencies if missing), leaving runtime deps like "@prisma/client",
"express", "pg", and "@prisma/adapter-pg" unchanged.
deployment-platforms/rest-express-docker-aws-ec2/README.md (1)

168-181: Consider rewording "SSHs" for clarity.

The static analysis flagged "SSHs" as potentially awkward. While grammatically defensible, "Connects via SSH" reads more naturally.

Additionally, the .github/ paths in the text are directory names (lowercase is correct), so the static analysis hints about GitHub capitalization appear to be false positives in this context.

📝 Optional wording improvement
 3. Pushes the image to ECR tagged with both the commit SHA and `latest`.
-4. SSHs into your EC2 instance.
+4. Connects via SSH to your EC2 instance.
 5. Runs `prisma migrate deploy` against your production database in a one-off container.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/README.md` around lines 168
- 181, In the "3. How deployment works" section, replace the awkward phrase
"SSHs into your EC2 instance." (step 4) with a clearer wording such as "Connects
to your EC2 instance via SSH." and leave the `.github/workflows/deploy.yml` and
`.github/workflows/` directory references in lowercase (they are directory
names), so do not change their capitalization.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@deployment-platforms/rest-express-docker-aws-ec2/package.json`:
- Around line 11-18: The package.json currently lists "prisma" under
"dependencies"; move it to "devDependencies" so the Prisma CLI is not installed
in production images. Edit the dependencies object to remove the "prisma":
"7.0.0" entry and add the same "prisma": "7.0.0" entry under a devDependencies
object (or create devDependencies if missing), leaving runtime deps like
"@prisma/client", "express", "pg", and "@prisma/adapter-pg" unchanged.

In `@deployment-platforms/rest-express-docker-aws-ec2/README.md`:
- Around line 168-181: In the "3. How deployment works" section, replace the
awkward phrase "SSHs into your EC2 instance." (step 4) with a clearer wording
such as "Connects to your EC2 instance via SSH." and leave the
`.github/workflows/deploy.yml` and `.github/workflows/` directory references in
lowercase (they are directory names), so do not change their capitalization.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 125ef143-f9a1-4752-8811-6a130163f7df

📥 Commits

Reviewing files that changed from the base of the PR and between c1acc0d and 652a95e.

📒 Files selected for processing (4)
  • deployment-platforms/rest-express-docker-aws-ec2/README.md
  • deployment-platforms/rest-express-docker-aws-ec2/package.json
  • deployment-platforms/rest-express-docker-aws-ec2/prisma/migrations/20240101000000_init/migration.sql
  • deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts
  • deployment-platforms/rest-express-docker-aws-ec2/prisma/migrations/20240101000000_init/migration.sql

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts (2)

24-26: Consider logging caught errors before returning 500.

The API contract is correct, but adding structured logs in these catch blocks will materially improve debugging and production incident triage.

Also applies to: 42-44, 68-70, 91-92, 112-113

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts`
around lines 24 - 26, The catch blocks in post.routes.ts do not log the caught
errors before responding with 500; update each catch (the ones around the route
handlers for listing/creating/updating/deleting posts) to accept the error
parameter (e.g., catch (err)) and call a structured logger or console.error with
context (include handler name, request identifiers like req.params or req.body
if available, and the error stack/message) before sending res.status(500).json({
error: 'Internal server error' }); ensure you update the catch blocks at the
occurrences noted (around lines shown) so they all log consistently.

49-53: Normalize and type-check title / authorEmail before DB calls.

Current truthy checks allow whitespace-only strings and non-string truthy values, which can degrade data quality or produce avoidable 500s instead of 400s.

Proposed hardening
 postRouter.post('/post', async (req: Request, res: Response) => {
   const { title, authorEmail, content } = req.body
-  if (!title || !authorEmail) {
+  const normalizedTitle = typeof title === 'string' ? title.trim() : ''
+  const normalizedAuthorEmail =
+    typeof authorEmail === 'string' ? authorEmail.trim() : ''
+
+  if (!normalizedTitle || !normalizedAuthorEmail) {
     res.status(400).json({ error: 'title and authorEmail are required' })
     return
   }
   try {
-    const author = await prisma.user.findUnique({ where: { email: authorEmail } })
+    const author = await prisma.user.findUnique({
+      where: { email: normalizedAuthorEmail },
+    })
     if (!author) {
-      res.status(404).json({ error: `No user found for email: ${authorEmail}` })
+      res
+        .status(404)
+        .json({ error: `No user found for email: ${normalizedAuthorEmail}` })
       return
     }
     const post = await prisma.post.create({
       data: {
-        title,
+        title: normalizedTitle,
         content,
-        author: { connect: { email: authorEmail } },
+        author: { connect: { email: normalizedAuthorEmail } },
       },
     })
     res.status(201).json(post)

Also applies to: 55-67

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts`
around lines 49 - 53, The handler currently only does a truthy check on
req.body.title and req.body.authorEmail which allows whitespace-only or
non-string values; update the validation to ensure title and authorEmail are
typeof 'string', trim() them and reject if the trimmed length === 0, and
validate authorEmail with a simple format check (e.g., regex) before making DB
calls so you return res.status(400) for bad input instead of hitting the DB and
risking 500s; apply the same normalization/validation to the other validation
block that uses title, authorEmail and content (referencing req.body, title,
authorEmail, content and the res.status(...) responses) so all incoming values
are type-checked and trimmed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts`:
- Around line 24-26: The catch blocks in post.routes.ts do not log the caught
errors before responding with 500; update each catch (the ones around the route
handlers for listing/creating/updating/deleting posts) to accept the error
parameter (e.g., catch (err)) and call a structured logger or console.error with
context (include handler name, request identifiers like req.params or req.body
if available, and the error stack/message) before sending res.status(500).json({
error: 'Internal server error' }); ensure you update the catch blocks at the
occurrences noted (around lines shown) so they all log consistently.
- Around line 49-53: The handler currently only does a truthy check on
req.body.title and req.body.authorEmail which allows whitespace-only or
non-string values; update the validation to ensure title and authorEmail are
typeof 'string', trim() them and reject if the trimmed length === 0, and
validate authorEmail with a simple format check (e.g., regex) before making DB
calls so you return res.status(400) for bad input instead of hitting the DB and
risking 500s; apply the same normalization/validation to the other validation
block that uses title, authorEmail and content (referencing req.body, title,
authorEmail, content and the res.status(...) responses) so all incoming values
are type-checked and trimmed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7bae76b7-a858-4fa8-955d-081482b7f5f2

📥 Commits

Reviewing files that changed from the base of the PR and between 652a95e and a6dd5cb.

📒 Files selected for processing (2)
  • deployment-platforms/rest-express-docker-aws-ec2/src/routes/post.routes.ts
  • deployment-platforms/rest-express-docker-aws-ec2/src/routes/user.routes.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • deployment-platforms/rest-express-docker-aws-ec2/src/routes/user.routes.ts

coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 17, 2026
- Update Dockerfile CMD to use 'dist/src/index.js' to match TypeScript output structure without rootDir constraint
- Update docker-compose.yml command to use correct compiled path
- Fix prisma.config.ts to use process.env.DATABASE_URL ?? '' instead of env() to avoid build-time failures when DATABASE_URL is not set
- Add 'declaration: true' to tsconfig.json for proper type definitions
- All API endpoints now pass e2e tests: POST /user, POST /post, GET /feed, PUT /publish/:id, GET /post/:id, DELETE /post/:id
- Validation and error handling confirmed working (400, 404, 500 responses)
@DiluDevX
Copy link
Author

✅ Build & Runtime Fixes Applied

Just pushed commit 81848f63f that resolves the critical build and runtime issues identified during testing:

Issues Fixed

  1. Module Resolution Error - Corrected Dockerfile CMD from dist/index.js to dist/src/index.js to match TypeScript output structure
  2. Build-time Database URL Failure - Changed prisma.config.ts to use process.env.DATABASE_URL ?? '' instead of env() to prevent build failures
  3. Docker Compose Path - Updated compose command to use correct compiled path
  4. TypeScript Configuration - Added declaration: true for proper type definitions

Verification

  • ✅ Docker image builds without errors
  • ✅ All migrations apply successfully
  • ✅ App starts and listens on port 3000
  • ✅ All 10 API endpoints tested and passing:
    • POST /user (201)
    • POST /post (201)
    • GET /feed (200)
    • PUT /publish/:id (200)
    • GET /post/:id (200)
    • DELETE /post/:id (200)
    • Validation errors (400)
    • Not found errors (404)
    • Error handling with try/catch (500)

Everything works end-to-end locally with docker compose up. The example is production-ready and fully tested! 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants