cda-app-fullstack-react

cda-app-fullstack-react

Pedagogical fullstack application split into two subprojects (Express/Prisma API and React/Parcel web client) with JWT authentication, protected routing, and MySQL persistence. The project covers the complete fullstack development cycle: data modeling, secured API routes, client-side state management, and technical documentation.

🎯 Context and goals

  • Build a fullstack training foundation covering end-to-end backend + frontend delivery.
  • Implement a secure user module (creation, authentication, token) on the API side.
  • Set up public/private navigation and centralized API calls on the web side.

πŸ› οΈ Deliverables

🧩 Design

{
  "scripts": {
    "watch": "npx tsc -w",
    "build": "npx tsc",
    "dev": "nodemon ./dist/index.js",
    "start": "node ./dist/index.js"
  },
  "devDependencies": {
    "@types/express": "^4.17.13",
    "argon2": "^0.28.2",
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "jsonwebtoken": "^8.5.1",
    "prisma": "^2.29.0",
    "typescript": "^4.3.5"
  },
  "dependencies": {
    "@prisma/client": "^2.29.0"
  }
}

Source: cda-app-fullstack-react/web/package.json

{
  "scripts": {
    "dev": "npx parcel ./src/index.html"
  },
  "devDependencies": {
    "axios": "^0.21.1",
    "parcel": "^2.0.0-rc.0",
    "react-redux": "^7.2.4",
    "react-router-dom": "^5.2.0",
    "redux": "^4.1.1",
    "redux-logger": "^3.0.6",
    "typescript": "^4.3.5"
  },
  "dependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  }
}
model Post {
  id        Int      @default(autoincrement()) @id
  title     String   @db.VarChar(255)
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int
}

model User {
  id       Int      @default(autoincrement()) @id
  email    String   @unique
  name     String?
  password String
  username String?
  posts    Post[]
  profile  Profile?
}

πŸ’» Development

export const createServer = async () => {
    const server: express.Application = express();

    server.use(express.json())

    server.use(cors({
        origin:"http://localhost:1234"
    }))

    server.use(APP_BASE_URL, mainRouter)

    return server
}

The main router composes root, post retrieval, and user sub-routes. Source: cda-app-fullstack-react/api/src/router.ts

const mainRouter: Router = Router();

mainRouter.get("/", (_: Request,res: Response) => {
    res.send('voici la racine')
})

mainRouter.get('/posts', async (_:Request, res:Response) => {
    const posts = await prisma.post.findMany();
    res.send(posts);
})

mainRouter.use('/users',userRouter)

The user creation use case hashes passwords with Argon2 and persists through a Prisma-backed repository. Source: cda-app-fullstack-react/api/src/modules/user/useCases/createUser/createUser.ts

const userAlreadyExists = await this.userRepo.exists(props.email)
if (userAlreadyExists) {
  return {
    success: false,
    message: 'User already exists'
  }
}

const hashPassword = await argon2.hash(props.password);
props.password = hashPassword;

await this.userRepo.create(props);

return {
  success: true,
  message: 'User is correctly created'
}

Authentication validates Argon2 hashes and generates a JWT, then the controller returns it as an HTTP-only cookie. Source: cda-app-fullstack-react/api/src/modules/user/useCases/login/login.ts

const user = await this.userRepo.getUserByEmail(email);

if (!user) {
  return {
    success: false,
    message: "Email or password missmatch"
  }
}

const passwordMatches = await argon2.verify(user.password, password)
if (!passwordMatches) {
  return {
    success: false,
    message: "Email or password missmatch"
  }
}

const jwtToken = sign({ id: user.id }, JWT_PASSPHRASE)
<Router>
  <Switch>
    <Route path="/register" component={Register} />
    <Route path="/login" component={Login} />
    <Layout>
      <AuthRoute exact path="/" component={Posts} />
      <AuthRoute path="/posts" component={Posts} />
    </Layout>
  </Switch>
</Router>

AuthRoute reads session data from local storage and redirects unauthenticated users. Source: cda-app-fullstack-react/web/src/js/components/authRoute.jsx

const AuthRoute = ({ component, path, exact, ...props }) => {
    const Component = component;
    const isLogged = useAuth();

    if (!isLogged)
        return <Redirect to="/login" />;

    return <Route exact={exact} path={path} render={() => <Component {...props} />} />;
};

const useAuth = () => {
    const auth = getLocalStorageItem('user');
    return auth !== null;
};

πŸ—οΈ DevOps & Quality

{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "experimentalDecorators": true,
    "esModuleInterop": true
  },
  "include": ["./src/**/*.ts"]
}

Source: cda-app-fullstack-react/web/src/js/store/store.js

import { createStore, applyMiddleware } from "redux";
import { createLogger } from "redux-logger";
import rootReducer from "./root";

const loggerMiddleware = createLogger();

export default preloadedState => {
    return createStore(
        rootReducer,
        preloadedState,
        applyMiddleware(
            loggerMiddleware,
        )
    );
};

πŸ“ˆ Results

  • Based on the analyzed Git history, the work spans 2021-08-09 -> 2026-02-14, with 27 commits across 2 contributors. The project delivers a working fullstack chain: Express/Prisma API, secure user registration/login, and a React frontend with protected routes. The api/web split and repository/use-case patterns improve technical responsibility boundaries. The technical benefit is a complete baseline to quickly prototype business applications with authentication.

πŸ”§ Technical environment

  • Backend: Node.js, Express, TypeScript, Prisma, MySQL, Argon2, JWT, CORS.
  • Frontend: React 17, React Router v5, Redux, Redux Logger, Parcel, Axios.
  • Architecture: api / web separation, versioned router, repository + use cases.
  • Security: password hashing, JWT token, HTTP-only cookie on login.
  • Quality: strict TS compilation, Redux middleware-based debugging.
🌐 View the project

Tech Stack

Backend
Express
Node.js
Bases de donnees (SGBD & SQL)
MySQL
Design Patterns & Architecture
Prisma
Frontend
React
Redux
TypeScript