CLI Scaffolder

Scaffold a full NDPA-compliant backend in seconds with create-ndpr — detects your stack and generates API routes, database schema, and layout wrappers automatically

Overview

create-ndpr is a zero-dependency interactive CLI that wires the NDPA compliance toolkit into an existing project. Run it once from your project root and it:

  • Inspects your project and detects the framework and ORM automatically
  • Asks a few questions about your organisation
  • Generates ready-to-use API routes, database schema, and layout files
  • Embeds your organisation name and DPO email in every generated file

No extra packages are required to run the CLI itself — it ships as a single .mjs file with no external dependencies, so npx can execute it straight from the npm registry on Node.js 18+.

Usage

Run the CLI from the root of an existing project — the same directory where your package.json and next.config.* live.

# Recommended — always uses the latest published version
npx @tantainnovative/create-ndpr

# Short alias (once the package is registered on npm)
npx create-ndpr

Run from the project root

The CLI reads package.json, next.config.*, prisma/schema.prisma, and drizzle.config.* from the current working directory. Always cd into your project root before running it.

What It Detects

Before prompting for anything, the CLI performs a silent stack-detection pass. The detected values are shown upfront and can be overridden at the framework and ORM prompts.

SignalDetected as
next.config.js / .ts / .mjsNext.js project
app/ or src/app/ directoryNext.js App Router
No app/ directory + next.config.*Next.js Pages Router
express in package.json depsExpress
@prisma/client or prisma in deps, or prisma/schema.prismaPrisma ORM
drizzle-orm / drizzle-kit in deps, or drizzle.config.*Drizzle ORM

What It Prompts For

The CLI walks through four short sections. Detected values are pre-selected as defaults so you can press Enter to confirm them.

1. Organisation details

  • Organisation name — embedded in every generated file (e.g. Acme Corp Nigeria Ltd)
  • DPO email address — the Data Protection Officer contact used in notices and policy headers

2. Framework

  • Next.js — App Router
  • Next.js — Pages Router
  • Express
  • None (generate shared files only)

Auto-detected from your project; you can override the choice.

3. Compliance modules

Multi-select. Defaults: consent, dsr, breach.

  • consent — NDPA §25-26 consent management
  • dsr — Data Subject Rights requests (§34-38)
  • breach — 72-hour breach notification workflow (§40)
  • policy — Privacy policy scaffolding
  • dpia — Data Protection Impact Assessment
  • lawful-basis — Lawful basis register (§25)
  • cross-border — Cross-border transfer management (§43)
  • ropa — Record of Processing Activities

4. ORM

  • Prisma — generates prisma/schema.prisma with NDPA models
  • Drizzle — generates src/drizzle/ndpr-schema.ts
  • None — skips database schema generation

A summary is shown before any files are written. You can abort at the confirmation prompt with no changes made to your project.

What Files It Generates

Every file is rendered from a template with your organisation name and DPO email substituted in. Files that already exist on disk are skipped rather than overwritten.

FileGenerated whenPurpose
.env.exampleAlwaysEnvironment variable template with DATABASE_URL and NDPA_DPO_EMAIL pre-filled
prisma/schema.prismaORM = Prisma (if not already present)Prisma schema with ConsentRecord, DSRRequest, BreachReport, and AuditLog models
src/drizzle/ndpr-schema.tsORM = DrizzleDrizzle table definitions mirroring the Prisma schema above
app/ndpr-layout.tsxNext.js App RouterNDPRProvider wrapper component — import and render around your children
app/api/consent/route.tsApp Router + consent modulePOST handler: saves consent records; GET handler: returns current consent
app/api/dsr/route.tsApp Router + dsr modulePOST handler: saves DSR submissions; GET handler: lists requests by email
app/api/breach/route.tsApp Router + breach modulePOST handler: records breach reports and triggers 72-hour timer logic
pages/api/consent.tsPages Router + consent moduleSame logic as the App Router variant, in Pages Router format
pages/api/dsr.tsPages Router + dsr modulePages Router DSR handler
pages/api/breach.tsPages Router + breach modulePages Router breach handler
src/ndpr/index.tsExpressExpress router factory — exports createNDPRRouter()
src/ndpr/routes/consent.tsExpress + consent moduleExpress consent route handler

If prisma/schema.prisma already exists the CLI skips it and prints the template path so you can merge the NDPA models manually.

Example: Next.js + Prisma

Below is an example session for a Next.js App Router project with Prisma, including consent, DSR, and breach modules.

$ npx @tantainnovative/create-ndpr

  ███╗   ██╗██████╗ ██████╗ ██████╗
  ████╗  ██║██╔══██╗██╔══██╗██╔══██╗
  ██╔██╗ ██║██║  ██║██████╔╝██████╔╝
  ██║╚██╗██║██║  ██║██╔═══╝ ██╔══██╗
  ██║ ╚████║██████╔╝██║     ██║  ██║
  ╚═╝  ╚═══╝╚═════╝ ╚═╝     ╚═╝  ╚═╝

  create-ndpr — NDPA compliance scaffolder
  Powered by @tantainnovative/ndpr-toolkit

  Detected project setup:
  Framework: Next.js (App Router)
  ORM:       Prisma

  Organisation details

  Organisation name (e.g. Acme Corp Nigeria Ltd): Acme Corp Nigeria Ltd
  DPO email address (e.g. dpo@acmecorp.ng): dpo@acme.ng

  Framework
  Which framework are you using?
    1) Next.js — App Router
    2) Next.js — Pages Router
    3) Express
    4) None (generate shared files only)
  Choice [1]:

  Compliance modules [default: 1,2,3]
    1) consent      — NDPA §25-26 consent management
    2) dsr          — Data Subject Rights requests (§34-38)
    3) breach       — Breach notification workflow (§40)
    4) policy       — Privacy policy generation
    5) dpia         — Data Protection Impact Assessment
    6) lawful-basis — Lawful basis register
    7) cross-border — Cross-border transfer management
    8) ropa         — Record of Processing Activities
  Enter numbers separated by commas (or press Enter for default):

  Database / ORM
  Which ORM are you using?
    1) Prisma
    2) Drizzle
    3) None (skip database schema)
  Choice [1]:

  Summary
  Organisation: Acme Corp Nigeria Ltd
  DPO email:    dpo@acme.ng
  Framework:    Next.js — App Router
  ORM:          Prisma
  Modules:      consent, dsr, breach

  Generate files? [Y/n]:

  Generating files...

  + .env.example
  + prisma/schema.prisma
  + src/app/ndpr-layout.tsx
  + src/app/api/consent/route.ts
  + src/app/api/dsr/route.ts
  + src/app/api/breach/route.ts

  Done! Files generated:
  ✓ .env.example
  ✓ prisma/schema.prisma
  ✓ src/app/ndpr-layout.tsx
  ✓ src/app/api/consent/route.ts
  ✓ src/app/api/dsr/route.ts
  ✓ src/app/api/breach/route.ts

  Next steps:

  1. Set your database URL in .env:
     DATABASE_URL="postgresql://user:password@localhost:5432/mydb_dev"

  2. Install the Prisma client and run migrations:
     pnpm add @prisma/client
     pnpm add -D prisma
     pnpm prisma migrate dev --name ndpr-init

  3. Install the ndpr-toolkit:
     pnpm add @tantainnovative/ndpr-toolkit

  4. Wrap your root layout with NDPRLayout:
     // src/app/layout.tsx
     import NDPRLayout from './ndpr-layout';
     // Render <NDPRLayout>{children}</NDPRLayout> inside your <body>

Next Steps After Scaffolding

With Prisma

# 1. Copy .env.example and set your database URL
cp .env.example .env

# 2. Install Prisma dependencies
pnpm add @prisma/client @tantainnovative/ndpr-toolkit
pnpm add -D prisma

# 3. Run the initial migration
pnpm prisma migrate dev --name ndpr-init

With Drizzle

cp .env.example .env

pnpm add drizzle-orm @paralleldrive/cuid2 @tantainnovative/ndpr-toolkit
pnpm add -D drizzle-kit

pnpm drizzle-kit push

Wire up Next.js layout

// src/app/layout.tsx
import NDPRLayout from '@/app/ndpr-layout';

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <NDPRLayout>{children}</NDPRLayout>
      </body>
    </html>
  );
}

Mount in Express

import express from 'express';
import { createNDPRRouter } from './src/ndpr';

const app = express();
app.use(express.json());
app.use('/api/ndpr', createNDPRRouter());

After wiring the layout

  • Add DSR and breach pages using the toolkit's preset components
  • Customise the consent banner position, styling, and categories
  • Optionally pass a locale prop to translate all UI strings
  • Replace the generated API handlers with your own persistence logic as needed