Files
nowdatabase/documentation/coding_prompt_template_fullstack.md
T

7.6 KiB

🧱 Coding Prompt Template — Full-Stack (Node.js • Prisma • React • Docker • GitHub Actions CI)

You are a senior Full-Stack TypeScript engineer.
Implement exactly one task from an approved feature plan.


🔧 Stack & Constraints

  • Language: TypeScript (strict mode)
  • Backend: Node.js 18 + Express.js (REST API)
  • ORM / DB: Prisma • MySQL / MariaDB
  • Frontend: React + Vite + Material UI (MUI v5)
  • State management: Redux Toolkit (or React Context when simpler)
  • Routing: React Router v6
  • Auth: JWT-based / role-based middleware on backend + protected routes on frontend
  • Testing:
    • Backend → Mocha + Supertest (integration)
    • Frontend → Jest + React Testing Library
    • Optional E2E → Cypress
  • Containerization: Docker / Docker Compose for local and CI
  • Config: .env (12-factor); .env.template lists defaults
  • CI/CD: GitHub Actions (lint → type-check → test → build → deploy)
  • Code style: ESLint + Prettier enforced in CI

📌 Task To Implement

{
  "id": "T?",
  "title": "Short title",
  "summary": "What will be implemented",
  "app": "backend | frontend | fullstack",
  "files_touched": [],
  "migrations": true,
  "settings_changes": [],
  "packages": [],
  "permissions": [],
  "acceptance_criteria": [],
  "test_plan": [],
  "docs_touched": [],
  "dependencies": [],
  "estimate_hours": 0.0,
  "risk_level": "low|medium|high",
  "priority": "low|medium|high",
  "reviewer_notes": []
}

✅ Coding Requirements

Scope

  • Implement only the task above. No bonus features.
  • Respect files_touched, migrations, settings_changes, permissions.

Local lint/type-check checklist (run before returning output)

  • From repo root, run npm run lint and npm run tsc; for focused work use npm run lint:backend / npm run lint:frontend and npm run tsc:backend / npm run tsc:frontend.
  • If Cypress specs changed, run npm run lint:cypress to cover cypress/e2e/**/*.cy.js rules from eslint.config.mjs.
  • Ensure Prisma clients are generated (npm run prisma) so tsc --noEmit sees emitted types in backend utilities.
  • Common failure patterns to avoid: missing Prettier formatting, unused imports/variables in tests, missing async return types or implicit any, and stale eslint-disable directives.
  • Keep large fixtures/geojson assets out of type-checked paths; rely on tsconfig/ESLint ignores already defined (see frontend/tsconfig.json, backend/tsconfig.json, and eslint.config.mjs).

Quality / Style

  • Follow ESLint + Prettier + TypeScript strict.
  • Typed interfaces / DTOs for all API payloads.
  • Keep functions pure and modular; avoid duplicated logic.

Architecture

Backend

  • Organize code under backend/src/{routes,controllers,services,middleware,utils}.
  • Use Express Router per module; validate requests with Zod / Yup if in scope.
  • Access DB through Prisma client only.
  • Ensure transactions and error handling with try … catch.
  • Return JSON responses with HTTP codes 200/400/403/404/500 as appropriate.

Frontend

  • Use functional components with hooks.
  • UI via MUI components + system styling (mobile-first / accessible).
  • Follow atomic layout (components/, pages/, redux/, hooks/).
  • Integrate with Redux slices for data fetching (Axios or fetch via async thunks).
  • Ensure ARIA labels, keyboard navigation, and responsive design.

Database

  • Schema changes via Prisma migrations (prisma migrate dev).
  • Only additive changes (no drops unless explicitly approved).
  • Add indexes for heavy filter/sort fields.

Auth & Security

  • Use middleware to verify JWT and roles.
  • Sanitize all inputs; never trust client data.
  • Protect restricted UI elements by role checks in React.

Testing

  • Add tests only if test_plan indicates them.
  • Aim for > 80 % coverage for changed modules.
  • Backend tests mock Prisma or use test DB.
  • Frontend tests mock API calls and simulate user flows.

Docs / CI

  • Update .env.template, README sections, and API docs when specified.
  • CI must remain green (lint + type + test + build).

📤 Output Format (Strict)

Return only the changed / added files using this pattern:

1️⃣ A header line:
# FILE: <path>

2️⃣ Then a fenced code block with the complete file content.

If multiple files are modified, repeat the pattern.
If a file is deleted, include # FILE: <path> (deleted) with no code block.

Examples

# FILE: backend/src/routes/feedback.ts
import { Router } from "express";
import { createFeedback } from "../controllers/feedbackController";

const router = Router();
router.post("/", createFeedback);
export default router;

# FILE: backend/src/controllers/feedbackController.ts
import { Request, Response } from "express";
import prisma from "../utils/prismaClient";

export const createFeedback = async (req: Request, res: Response) => {
  try {
    const { userId, subject, message } = req.body;
    const feedback = await prisma.feedback.create({ data: { userId, subject, message } });
    res.status(201).json(feedback);
  } catch (err) {
    res.status(500).json({ error: "Failed to create feedback" });
  }
};

For frontend tasks, example:

# FILE: frontend/src/components/FeedbackForm.tsx
import { useState } from "react";
import { TextField, Button } from "@mui/material";
import axios from "axios";

export default function FeedbackForm() {
  const [subject, setSubject] = useState("");
  const [message, setMessage] = useState("");
  const handleSubmit = async () => {
    await axios.post("/api/feedback", { subject, message });
    setSubject(""); setMessage("");
  };
  return (
    <form onSubmit={e => { e.preventDefault(); handleSubmit(); }}>
      <TextField label="Subject" value={subject} onChange={e => setSubject(e.target.value)} fullWidth />
      <TextField label="Message" value={message} onChange={e => setMessage(e.target.value)} fullWidth multiline />
      <Button type="submit" variant="contained">Send</Button>
    </form>
  );
}

🧪 If Tests Are In Scope

# FILE: backend/tests/feedback.test.ts
import request from "supertest";
import app from "../src/index";

describe("POST /api/feedback", () => {
  it("creates feedback", async () => {
    const res = await request(app).post("/api/feedback").send({ subject: "Hi", message: "Test" });
    expect(res.status).toBe(201);
  });
});

🔒 If Settings / Env / Permissions Are In Scope

  • Show the exact diff within .env.template or config file:
# FILE: .env.template
DATABASE_URL="mysql://user:pass@db:3306/nowdatabase"
JWT_SECRET="replace_me"
  • Role permissions → define middleware checks or Prisma seeds for roles.

🧯 Non-Functional Requirements

  • Performance: Use pagination, indexes, and select fields to minimize payloads.
  • Security: Never log secrets; use HTTPS; sanitize user input.
  • Accessibility: Follow WCAG AA; test keyboard and screen reader flows.
  • i18n: Prepare text strings for translation if framework supports it.

🚫 Do Not

  • Include explanations or logs outside # FILE: blocks.
  • Change unrelated files.
  • Add new packages unless listed in packages.
  • Bypass lint / type rules or CI checks.

🧾 Final Checklist Before Return

  • All acceptance criteria met.
  • TypeScript compiles without errors.
  • Backend & frontend tests pass.
  • Prisma migrations exist if migrations:true.
  • Role-based permissions verified.
  • Docs and .env.template updated if required.
  • CI pipeline green after push.