@tantainnovative/create-ndpr 0.1.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # create-ndpr
2
2
 
3
- CLI scaffolder for [NDPA](https://ndpr.gov.ng/) compliance using [`@tantainnovative/ndpr-toolkit`](https://github.com/tantainnovative/ndpr-toolkit).
3
+ CLI scaffolder for Nigeria [NDPA 2023](https://ndpc.gov.ng/) / NDPC GAID 2025 compliance using [`@tantainnovative/ndpr-toolkit`](https://github.com/mr-tanta/ndpr-toolkit).
4
4
 
5
5
  ## Usage
6
6
 
@@ -14,100 +14,109 @@ Or with the short alias (once published to npm):
14
14
  npx create-ndpr
15
15
  ```
16
16
 
17
- Run this from the root of an existing project. The CLI detects your stack and generates the right files with no manual copy-pasting.
17
+ Run the CLI from an existing project root. It detects the framework and ORM, asks which modules you need, and writes stack-specific integration files without overwriting an existing Prisma schema.
18
18
 
19
19
  ## What it does
20
20
 
21
- 1. **Detects your project setup** — checks for `next.config.*`, `express` in `package.json`, an `app/` directory (App Router vs Pages Router), `prisma/schema.prisma`, and `drizzle.config.*`.
21
+ 1. Detects `next.config.*`, Express dependencies, App vs Pages Router directories, `prisma/schema.prisma`, and `drizzle.config.*`.
22
+ 2. Prompts for the organisation, DPO email, framework, ORM, and compliance modules.
23
+ 3. Generates tenant-scoped routes, a fail-closed authentication integration seam, persistence schemas, client wiring, and an `ndpr audit` CI gate.
22
24
 
23
- 2. **Prompts for a few details:**
24
- - Organisation name
25
- - DPO (Data Protection Officer) email address
26
- - Framework (auto-detected, can override)
27
- - ORM: Prisma / Drizzle / None
28
- - Which compliance modules to include
29
-
30
- 3. **Generates files** tailored to your stack.
31
-
32
- ## What it generates
25
+ ## Generated files
33
26
 
34
27
  | File | When |
35
28
  |------|------|
36
29
  | `.env.example` | Always |
37
- | `prisma/schema.prisma` | ORM = Prisma (skips if already exists) |
38
- | `src/drizzle/ndpr-schema.ts` | ORM = Drizzle |
39
- | `app/ndpr-layout.tsx` | Next.js App Router |
40
- | `app/api/consent/route.ts` | Next.js + consent module |
41
- | `app/api/dsr/route.ts` | Next.js + dsr module |
42
- | `app/api/breach/route.ts` | Next.js + breach module |
43
- | `pages/api/consent.ts` | Next.js Pages Router + consent |
44
- | `pages/api/dsr.ts` | Next.js Pages Router + dsr |
45
- | `pages/api/breach.ts` | Next.js Pages Router + breach |
46
- | `src/ndpr/index.ts` | Express |
47
- | `src/ndpr/routes/consent.ts` | Express + consent module |
48
-
49
- All generated files use `{{ORG_NAME}}` and `{{DPO_EMAIL}}` substituted with your answers.
30
+ | `ndpr.audit.json` and `.github/workflows/ndpr-audit.yml` | Always |
31
+ | `prisma/schema.prisma` | Prisma; skipped when a schema already exists so it can be merged manually |
32
+ | `src/drizzle/ndpr-schema.ts` and `src/drizzle/index.ts` | Drizzle |
33
+ | `ndpr/request-context.ts` or `src/ndpr/request-context.ts` | Next.js |
34
+ | `app/ndpr-layout.tsx` or `pages/ndpr-provider.tsx` | Next.js + consent |
35
+ | `app/api/<module>/route.ts` | Next.js App Router backend modules |
36
+ | `pages/api/<module>.ts` | Next.js Pages Router backend modules |
37
+ | `src/ndpr/request-context.ts`, `src/ndpr/index.ts` | Express |
38
+ | `src/ndpr/routes/<module>.ts` | Express backend modules |
39
+
40
+ Maintained persistence routes are generated for consent, DSR, breach, DPIA, lawful-basis, and cross-border modules. Policy and ROPA choices remain represented in the compliance-audit configuration but do not currently generate backend routes.
41
+
42
+ The breach create route returns an `ndpcReadiness` summary showing missing GAID 2025 Article 33(5) notification evidence and the remaining time in the 72-hour window. Reporter identity is taken from the verified staff profile, never from request-body reporter fields.
43
+
44
+ ## Security contract
45
+
46
+ Generated routes intentionally fail closed until you connect `resolveVerifiedNDPRActor` in the request-context file to verified server authentication:
47
+
48
+ - `NDPR_TENANT_ID` is the server-controlled tenant boundary. Request bodies, query parameters, cookies, and arbitrary headers are not tenant authority.
49
+ - A verified actor contains `id`, `displayName`, `email`, optional `department` and account `subjectId`, plus server-mapped roles.
50
+ - Staff routes require exactly `ndpr:staff` or `ndpr:admin`; authentication without one of those roles returns 403.
51
+ - Anonymous consent/DSR access accepts only an `anon_<UUID>` capability in `X-NDPR-Subject-Id`. It never grants staff access.
52
+ - Account actor, profile, subject, and role values must come from a verified session—not client input.
53
+ - Prisma and Drizzle business mutations write their accountability audit row in the same transaction.
54
+ - Consent replacement is serializable, replay-aware, and protected by one-active-record uniqueness. Preserve the generated `timestamp` and `hasInteracted` fields and apply the generated unique index in your migration.
55
+ - The no-ORM stores are development-only and are not durable compliance evidence.
50
56
 
51
57
  ## Modules
52
58
 
53
- | Module | NDPA reference | Description |
54
- |--------|---------------|-------------|
55
- | `consent` | §25–26 | Consent collection, storage, and withdrawal |
56
- | `dsr` | §34–38 | Data subject rights request intake and tracking |
57
- | `breach` | §40 | 72-hour breach notification workflow |
58
- | `policy` | | Privacy policy scaffolding |
59
- | `dpia` | | Data Protection Impact Assessment |
60
- | `lawful-basis` | §25 | Lawful basis register |
61
- | `cross-border` | §43 | Cross-border data transfer management |
62
- | `ropa` | Accountability | Record of Processing Activities |
59
+ | Module | NDPA reference | Generated backend |
60
+ |--------|----------------|:-----------------:|
61
+ | `consent` | §25–26 | Yes |
62
+ | `dsr` | §34–38 | Yes |
63
+ | `breach` | §40 | Yes |
64
+ | `dpia` | §28 | Yes |
65
+ | `lawful-basis` | §25 | Yes |
66
+ | `cross-border` | §41–43 | Yes |
67
+ | `policy` | §27 | Audit config only |
68
+ | `ropa` | §29 | Audit config only |
63
69
 
64
70
  ## After generation
65
71
 
66
- ### With Prisma
72
+ ### Prisma
67
73
 
68
74
  ```bash
69
- # Copy .env.example → .env and set DATABASE_URL
70
75
  cp .env.example .env
71
-
72
- # Install dependencies
73
76
  pnpm add @prisma/client @tantainnovative/ndpr-toolkit
74
77
  pnpm add -D prisma
75
-
76
- # Run migrations
77
78
  pnpm prisma migrate dev --name ndpr-init
78
79
  ```
79
80
 
80
- ### With Drizzle
81
+ If the CLI skipped an existing `prisma/schema.prisma`, merge the generated models and indexes deliberately before migrating.
82
+
83
+ ### Drizzle
81
84
 
82
85
  ```bash
83
86
  cp .env.example .env
84
-
85
87
  pnpm add drizzle-orm @paralleldrive/cuid2 @tantainnovative/ndpr-toolkit
86
88
  pnpm add -D drizzle-kit
89
+ ```
90
+
91
+ Pass your existing Drizzle instance to the generated seam once during server startup, then run the migration command appropriate to your pinned Drizzle setup:
92
+
93
+ ```ts
94
+ import { configureNDPRDatabase } from './src/drizzle';
95
+ import { db } from './src/db';
87
96
 
88
- pnpm drizzle-kit push
97
+ configureNDPRDatabase(db);
89
98
  ```
90
99
 
91
- ### Next.js wire up the layout
100
+ ### Next.js App Router
92
101
 
93
102
  ```tsx
94
103
  // app/layout.tsx
95
- import NDPRLayout from '@/app/ndpr-layout';
104
+ import NDPRClientProvider from './ndpr-layout';
96
105
 
97
- export default async function RootLayout({ children }) {
106
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
98
107
  return (
99
108
  <html lang="en">
100
109
  <body>
101
- <NDPRLayout>
102
- {children}
103
- </NDPRLayout>
110
+ <NDPRClientProvider>{children}</NDPRClientProvider>
104
111
  </body>
105
112
  </html>
106
113
  );
107
114
  }
108
115
  ```
109
116
 
110
- ### Express mount the router
117
+ For Pages Router, wrap your page component with the generated provider from `pages/ndpr-provider.tsx` in `pages/_app.tsx`.
118
+
119
+ ### Express
111
120
 
112
121
  ```ts
113
122
  import express from 'express';
@@ -118,13 +127,23 @@ app.use(express.json());
118
127
  app.use('/api/ndpr', createNDPRRouter());
119
128
  ```
120
129
 
130
+ ## Compliance as code
131
+
132
+ Every scaffold includes `ndpr.audit.json` and a GitHub Actions workflow that runs `ndpr audit`. Update the configuration to match the real implementation, then use a minimum score as a CI gate:
133
+
134
+ ```bash
135
+ npx ndpr audit --min-score 70
136
+ ```
137
+
138
+ The audit is implementation support, not legal advice. Verify current NDPC requirements before relying on its output for a filing.
139
+
121
140
  ## Requirements
122
141
 
123
142
  - Node.js 18+
124
- - Zero external dependencies works with `npx` out of the box
143
+ - The CLI itself has zero runtime dependencies.
125
144
 
126
145
  ## Links
127
146
 
128
- - Toolkit docs: https://ndpr-toolkit.tantainnovative.com
129
- - GitHub: https://github.com/tantainnovative/ndpr-toolkit
130
- - NDPC: https://ndpr.gov.ng
147
+ - Toolkit docs: https://ndprtoolkit.com.ng
148
+ - GitHub: https://github.com/mr-tanta/ndpr-toolkit
149
+ - NDPC: https://ndpc.gov.ng